Browse Source

Update dpf

tags/1.9.4
falkTX 11 years ago
parent
commit
f324c8c68c
48 changed files with 1021 additions and 1048 deletions
  1. +2
    -0
      source/modules/dgl/App.hpp
  2. +3
    -46
      source/modules/dgl/Base.hpp
  3. +2
    -0
      source/modules/dgl/CairoWidget.hpp
  4. +6
    -0
      source/modules/dgl/Geometry.hpp
  5. +2
    -0
      source/modules/dgl/Image.hpp
  6. +2
    -0
      source/modules/dgl/ImageAboutWindow.hpp
  7. +2
    -0
      source/modules/dgl/ImageButton.hpp
  8. +2
    -0
      source/modules/dgl/ImageKnob.hpp
  9. +4
    -0
      source/modules/dgl/ImageSlider.hpp
  10. +3
    -1
      source/modules/dgl/StandaloneWindow.hpp
  11. +2
    -0
      source/modules/dgl/Widget.hpp
  12. +2
    -0
      source/modules/dgl/Window.hpp
  13. +1
    -1
      source/modules/dgl/src/App.cpp
  14. +60
    -27
      source/modules/dgl/src/ImageSlider.cpp
  15. +37
    -37
      source/modules/dgl/src/Window.cpp
  16. +58
    -9
      source/modules/distrho/DistrhoPlugin.hpp
  17. +9
    -6
      source/modules/distrho/DistrhoUI.hpp
  18. +60
    -577
      source/modules/distrho/DistrhoUtils.hpp
  19. +58
    -43
      source/modules/distrho/src/DistrhoDefines.h
  20. +2
    -2
      source/modules/distrho/src/DistrhoPluginCarla.cpp
  21. +118
    -81
      source/modules/distrho/src/DistrhoPluginInternal.hpp
  22. +37
    -34
      source/modules/distrho/src/DistrhoPluginLADSPA+DSSI.cpp
  23. +112
    -4
      source/modules/distrho/src/DistrhoPluginLV2.cpp
  24. +8
    -0
      source/modules/distrho/src/DistrhoPluginLV2export.cpp
  25. +3
    -3
      source/modules/distrho/src/DistrhoPluginVST.cpp
  26. +4
    -4
      source/modules/distrho/src/DistrhoUI.cpp
  27. +5
    -5
      source/modules/distrho/src/DistrhoUIDSSI.cpp
  28. +40
    -24
      source/modules/distrho/src/DistrhoUIInternal.hpp
  29. +25
    -7
      source/modules/distrho/src/DistrhoUILV2.cpp
  30. +154
    -26
      source/modules/distrho/src/lv2/atom-forge.h
  31. +16
    -22
      source/modules/distrho/src/lv2/atom-helpers.h
  32. +58
    -13
      source/modules/distrho/src/lv2/atom-util.h
  33. +1
    -1
      source/modules/distrho/src/lv2/atom.h
  34. +18
    -15
      source/modules/distrho/src/lv2/event-helpers.h
  35. +2
    -1
      source/modules/distrho/src/lv2/logger.h
  36. +6
    -6
      source/modules/distrho/src/lv2/lv2-midifunctions.h
  37. +2
    -1
      source/modules/distrho/src/lv2/lv2.h
  38. +8
    -6
      source/modules/distrho/src/lv2/lv2_external_ui.h
  39. +14
    -0
      source/modules/distrho/src/lv2/lv2_rtmempool.h
  40. +2
    -2
      source/modules/distrho/src/lv2/morph.h
  41. +24
    -23
      source/modules/distrho/src/lv2/patch.h
  42. +30
    -3
      source/modules/distrho/src/lv2/ui.h
  43. +1
    -1
      source/modules/distrho/src/lv2/uri-map.h
  44. +1
    -1
      source/modules/distrho/src/lv2/urid.h
  45. +1
    -1
      source/modules/distrho/src/lv2/worker.h
  46. +1
    -0
      source/modules/native-plugins/3bandeq/DistrhoUI3BandEQ.cpp
  47. +1
    -0
      source/modules/native-plugins/3bandsplitter/DistrhoUI3BandSplitter.cpp
  48. +12
    -15
      source/utils/CarlaMutex.hpp

+ 2
- 0
source/modules/dgl/App.hpp View File

@@ -55,6 +55,8 @@ private:
void _removeWindow(Window* const window);
void _oneShown();
void _oneHidden();

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(App)
};

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


+ 3
- 46
source/modules/dgl/Base.hpp View File

@@ -17,42 +17,9 @@
#ifndef DGL_BASE_HPP_INCLUDED
#define DGL_BASE_HPP_INCLUDED

/* Compatibility with non-clang compilers */
#ifndef __has_feature
# define __has_feature(x) 0
#endif
#ifndef __has_extension
# define __has_extension __has_feature
#endif

/* Check OS */
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
# define DGL_OS_WINDOWS 1
#elif defined(__APPLE__)
# define DGL_OS_MAC 1
#elif defined(__HAIKU__)
# define DGL_OS_HAIKU 1
#elif defined(__linux__) || defined(__linux)
# define DGL_OS_LINUX 1
#endif
#include "../distrho/extra/d_leakdetector.hpp"

/* Check for C++11 support */
#if defined(HAVE_CPP11_SUPPORT)
# define PROPER_CPP11_SUPPORT
#elif __cplusplus >= 201103L || (defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 405) || __has_extension(cxx_noexcept)
# define PROPER_CPP11_SUPPORT
# if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407) || ! __has_extension(cxx_override_control)
# define override // gcc4.7+ only
# define final // gcc4.7+ only
# endif
#endif

#ifndef PROPER_CPP11_SUPPORT
# define noexcept throw()
# define override
# define final
# define nullptr (0)
#endif
// -----------------------------------------------------------------------

/* Define namespace */
#ifndef DGL_NAMESPACE
@@ -64,7 +31,7 @@
#define USE_NAMESPACE_DGL using namespace DGL_NAMESPACE;

/* GL includes */
#ifdef DGL_OS_MAC
#ifdef DISTRHO_OS_MAC
# include <OpenGL/gl.h>
#else
# include <GL/gl.h>
@@ -137,16 +104,6 @@ enum Modifier {
MODIFIER_SUPER = 1 << 3 /**< Mod4/Command/Windows key */
};

/*
* Cross-platform sleep function.
*/
void sleep(unsigned int secs);

/*
* Cross-platform msleep function.
*/
void msleep(unsigned int msecs);

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

END_NAMESPACE_DGL


+ 2
- 0
source/modules/dgl/CairoWidget.hpp View File

@@ -197,6 +197,8 @@ private:
cairo_t* fContext;
cairo_surface_t* fSurface;
GLuint fTextureId;

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CairoWidget)
};

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


+ 6
- 0
source/modules/dgl/Geometry.hpp View File

@@ -49,6 +49,8 @@ public:
private:
T fX, fY;
template<typename> friend class Rectangle;

DISTRHO_PREVENT_HEAP_ALLOCATION
};

// -----------------------------------------------------------------------
@@ -78,6 +80,8 @@ public:
private:
T fWidth, fHeight;
template<typename> friend class Rectangle;

DISTRHO_PREVENT_HEAP_ALLOCATION
};

// -----------------------------------------------------------------------
@@ -124,6 +128,8 @@ public:
private:
Point<T> fPos;
Size<T> fSize;

DISTRHO_PREVENT_HEAP_ALLOCATION
};

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


+ 2
- 0
source/modules/dgl/Image.hpp View File

@@ -59,6 +59,8 @@ private:
GLenum fFormat;
GLenum fType;
GLuint fTextureId;

DISTRHO_PREVENT_HEAP_ALLOCATION
};

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


+ 2
- 0
source/modules/dgl/ImageAboutWindow.hpp View File

@@ -47,6 +47,8 @@ protected:

private:
Image fImgBackground;

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ImageAboutWindow)
};

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


+ 2
- 0
source/modules/dgl/ImageButton.hpp View File

@@ -55,6 +55,8 @@ private:
int fCurButton;

Callback* fCallback;

DISTRHO_LEAK_DETECTOR(ImageButton)
};

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


+ 2
- 0
source/modules/dgl/ImageKnob.hpp View File

@@ -83,6 +83,8 @@ private:
int fImgLayerCount;
Rectangle<int> fKnobArea;
GLuint fTextureId;

DISTRHO_LEAK_DETECTOR(ImageKnob)
};

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


+ 4
- 0
source/modules/dgl/ImageSlider.hpp View File

@@ -47,6 +47,7 @@ public:
void setEndPos(const Point<int>& endPos);
void setEndPos(int x, int y);

void setInverted(bool inverted);
void setRange(float min, float max);
void setStep(float step);
void setValue(float value, bool sendCallback = false);
@@ -67,6 +68,7 @@ private:
float fValueTmp;

bool fDragging;
bool fInverted;
int fStartedX;
int fStartedY;

@@ -77,6 +79,8 @@ private:
Rectangle<int> fSliderArea;

void _recheckArea();

DISTRHO_LEAK_DETECTOR(ImageSlider)
};

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


+ 3
- 1
source/modules/dgl/StandaloneWindow.hpp View File

@@ -68,8 +68,10 @@ public:
}

protected:
App fApp;
App fApp;
Window fWindow;

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(StandaloneWindow)
};

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


+ 2
- 0
source/modules/dgl/Widget.hpp View File

@@ -97,6 +97,8 @@ private:

friend class CairoWidget;
friend class Window;

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Widget)
};

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


+ 2
- 0
source/modules/dgl/Window.hpp View File

@@ -77,6 +77,8 @@ private:
void _addWidget(Widget* const widget);
void _removeWidget(Widget* const widget);
void _idle();

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Window)
};

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


+ 1
- 1
source/modules/dgl/src/App.cpp View File

@@ -68,7 +68,7 @@ void App::exec()
while (pData->doLoop)
{
idle();
msleep(10);
d_msleep(10);
}
}



+ 60
- 27
source/modules/dgl/src/ImageSlider.cpp View File

@@ -31,6 +31,7 @@ ImageSlider::ImageSlider(Window& parent, const Image& image)
fValue(0.5f),
fValueTmp(fValue),
fDragging(false),
fInverted(false),
fStartedX(0),
fStartedY(0),
fCallback(nullptr)
@@ -47,6 +48,7 @@ ImageSlider::ImageSlider(Widget* widget, const Image& image)
fValue(0.5f),
fValueTmp(fValue),
fDragging(false),
fInverted(false),
fStartedX(0),
fStartedY(0),
fCallback(nullptr)
@@ -63,6 +65,7 @@ ImageSlider::ImageSlider(const ImageSlider& imageSlider)
fValue(imageSlider.fValue),
fValueTmp(fValue),
fDragging(false),
fInverted(imageSlider.fInverted),
fStartedX(0),
fStartedY(0),
fCallback(imageSlider.fCallback),
@@ -100,6 +103,15 @@ void ImageSlider::setEndPos(int x, int y)
setEndPos(Point<int>(x, y));
}

void ImageSlider::setInverted(bool inverted)
{
if (fInverted == inverted)
return;

fInverted = inverted;
repaint();
}

void ImageSlider::setRange(float min, float max)
{
if (fValue < min)
@@ -154,24 +166,33 @@ void ImageSlider::onDisplay()
#if 0 // DEBUG, paints slider area
glColor3f(0.4f, 0.5f, 0.1f);
glRecti(fSliderArea.getX(), fSliderArea.getY(), fSliderArea.getX()+fSliderArea.getWidth(), fSliderArea.getY()+fSliderArea.getHeight());
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
#endif

float normValue = (fValue - fMinimum) / (fMaximum - fMinimum);

int x, y;

if (fStartPos.getX() == fEndPos.getX())
if (fStartPos.getY() == fEndPos.getY())
{
x = fStartPos.getX();
y = fEndPos.getY() - static_cast<int>(normValue*static_cast<float>(fEndPos.getY()-fStartPos.getY()));
}
else if (fStartPos.getY() == fEndPos.getY())
{
x = fEndPos.getX() - static_cast<int>(normValue*static_cast<float>(fEndPos.getX()-fStartPos.getX()));
// horizontal
if (fInverted)
x = fEndPos.getX() - static_cast<int>(normValue*static_cast<float>(fEndPos.getX()-fStartPos.getX()));
else
x = fStartPos.getX() + static_cast<int>(normValue*static_cast<float>(fEndPos.getX()-fStartPos.getX()));
y = fStartPos.getY();
}
else
return;
{
// vertical
x = fStartPos.getX();

if (fInverted)
y = fEndPos.getY() - static_cast<int>(normValue*static_cast<float>(fEndPos.getY()-fStartPos.getY()));
else
y = fStartPos.getY() + static_cast<int>(normValue*static_cast<float>(fEndPos.getY()-fStartPos.getY()));
}

fImage.draw(x, y);
}
@@ -188,22 +209,23 @@ bool ImageSlider::onMouse(int button, bool press, int x, int y)

float vper;

if (fStartPos.getX() == fEndPos.getX())
{
// vertical
vper = float(y - fSliderArea.getY()) / float(fSliderArea.getHeight());
}
else if (fStartPos.getY() == fEndPos.getY())
if (fStartPos.getY() == fEndPos.getY())
{
// horizontal
vper = float(x - fSliderArea.getX()) / float(fSliderArea.getWidth());
}
else
return false;
{
// vertical
vper = float(y - fSliderArea.getY()) / float(fSliderArea.getHeight());
}

float value;

value = fMaximum - vper * (fMaximum - fMinimum);
if (fInverted)
value = fMaximum - vper * (fMaximum - fMinimum);
else
value = fMinimum + vper * (fMaximum - fMinimum);

if (value < fMinimum)
{
@@ -250,7 +272,7 @@ bool ImageSlider::onMotion(int x, int y)
if (! fDragging)
return false;

bool horizontal = fStartPos.getY() == fEndPos.getY();
const bool horizontal = fStartPos.getY() == fEndPos.getY();

if ((horizontal && fSliderArea.containsX(x)) || (fSliderArea.containsY(y) && ! horizontal))
{
@@ -269,7 +291,10 @@ bool ImageSlider::onMotion(int x, int y)

float value;

value = fMaximum - vper * (fMaximum - fMinimum);
if (fInverted)
value = fMaximum - vper * (fMaximum - fMinimum);
else
value = fMinimum + vper * (fMaximum - fMinimum);

if (value < fMinimum)
{
@@ -290,13 +315,19 @@ bool ImageSlider::onMotion(int x, int y)

setValue(value, true);
}
else if (y < fSliderArea.getY())
else if (horizontal)
{
setValue(fMaximum, true);
if (x < fSliderArea.getX())
setValue(fInverted ? fMaximum : fMinimum, true);
else
setValue(fInverted ? fMinimum : fMaximum, true);
}
else
{
setValue(fMinimum, true);
if (y < fSliderArea.getY())
setValue(fInverted ? fMaximum : fMinimum, true);
else
setValue(fInverted ? fMinimum : fMaximum, true);
}

return true;
@@ -304,19 +335,21 @@ bool ImageSlider::onMotion(int x, int y)

void ImageSlider::_recheckArea()
{
if (fStartPos.getX() == fEndPos.getX())
if (fStartPos.getY() == fEndPos.getY())
{
// horizontal
fSliderArea = Rectangle<int>(fStartPos.getX(),
fStartPos.getY(),
fImage.getWidth(),
fEndPos.getY() + fImage.getHeight() - fStartPos.getY());
fEndPos.getX() + fImage.getWidth() - fStartPos.getX(),
fImage.getHeight());
}
else if (fStartPos.getY() == fEndPos.getY())
else
{
// vertical
fSliderArea = Rectangle<int>(fStartPos.getX(),
fStartPos.getY(),
fEndPos.getX() + fImage.getWidth() - fStartPos.getX(),
fImage.getHeight());
fImage.getWidth(),
fEndPos.getY() + fImage.getHeight() - fStartPos.getY());
}
}



+ 37
- 37
source/modules/dgl/src/Window.cpp View File

@@ -24,16 +24,16 @@

#include "pugl/pugl.h"

#if defined(DGL_OS_WINDOWS)
#if defined(DISTRHO_OS_WINDOWS)
# include "pugl/pugl_win.cpp"
#elif defined(DGL_OS_MAC)
#elif defined(DISTRHO_OS_MAC)
# include "pugl/pugl_osx_extended.h"
extern "C" {
struct PuglViewImpl {
int width;
int height;
};}
#elif defined(DGL_OS_LINUX)
#elif defined(DISTRHO_OS_LINUX)
# include <sys/types.h>
# include <unistd.h>
extern "C" {
@@ -77,12 +77,12 @@ public:
fVisible(false),
fResizable(true),
fUsingEmbed(false),
#if defined(DGL_OS_WINDOWS)
#if defined(DISTRHO_OS_WINDOWS)
hwnd(0)
#elif defined(DGL_OS_LINUX)
#elif defined(DISTRHO_OS_LINUX)
xDisplay(nullptr),
xWindow(0)
#elif defined(DGL_OS_MAC)
#elif defined(DISTRHO_OS_MAC)
fNeedsIdle(true)
#else
_dummy('\0')
@@ -101,12 +101,12 @@ public:
fResizable(true),
fUsingEmbed(false),
fModal(parent.pData),
#if defined(DGL_OS_WINDOWS)
#if defined(DISTRHO_OS_WINDOWS)
hwnd(0)
#elif defined(DGL_OS_LINUX)
#elif defined(DISTRHO_OS_LINUX)
xDisplay(nullptr),
xWindow(0)
#elif defined(DGL_OS_MAC)
#elif defined(DISTRHO_OS_MAC)
fNeedsIdle(false)
#else
_dummy('\0')
@@ -115,7 +115,7 @@ public:
DBG("Creating window with parent..."); DBGF;
init();

#ifdef DGL_OS_LINUX
#ifdef DISTRHO_OS_LINUX
const PuglInternals* const parentImpl(parent.pData->fView->impl);

XSetTransientForHint(xDisplay, xWindow, parentImpl->win);
@@ -130,12 +130,12 @@ public:
fVisible(parentId != 0),
fResizable(parentId == 0),
fUsingEmbed(parentId != 0),
#if defined(DGL_OS_WINDOWS)
#if defined(DISTRHO_OS_WINDOWS)
hwnd(0)
#elif defined(DGL_OS_LINUX)
#elif defined(DISTRHO_OS_LINUX)
xDisplay(nullptr),
xWindow(0)
#elif defined(DGL_OS_MAC)
#elif defined(DISTRHO_OS_MAC)
fNeedsIdle(false)
#else
_dummy('\0')
@@ -178,11 +178,11 @@ public:
puglSetReshapeFunc(fView, onReshapeCallback);
puglSetCloseFunc(fView, onCloseCallback);

#if defined(DGL_OS_WINDOWS)
#if defined(DISTRHO_OS_WINDOWS)
PuglInternals* impl = fView->impl;
hwnd = impl->hwnd;
assert(hwnd != 0);
#elif defined(DGL_OS_LINUX)
#elif defined(DISTRHO_OS_LINUX)
PuglInternals* impl = fView->impl;
xDisplay = impl->display;
xWindow = impl->win;
@@ -225,9 +225,9 @@ public:
fView = nullptr;
}

#if defined(DGL_OS_WINDOWS)
#if defined(DISTRHO_OS_WINDOWS)
hwnd = 0;
#elif defined(DGL_OS_LINUX)
#elif defined(DISTRHO_OS_LINUX)
xDisplay = nullptr;
xWindow = 0;
#endif
@@ -259,7 +259,7 @@ public:
for (; fVisible && fModal.enabled;)
{
idle();
msleep(10);
d_msleep(10);
}

exec_fini();
@@ -275,13 +275,13 @@ public:
void focus()
{
DBG("Window focus\n");
#if defined(DGL_OS_WINDOWS)
#if defined(DISTRHO_OS_WINDOWS)
SetForegroundWindow(hwnd);
SetActiveWindow(hwnd);
SetFocus(hwnd);
#elif defined(DGL_OS_MAC)
#elif defined(DISTRHO_OS_MAC)
puglImplFocus(fView);
#elif defined(DGL_OS_LINUX)
#elif defined(DISTRHO_OS_LINUX)
XRaiseWindow(xDisplay, xWindow);
XSetInputFocus(xDisplay, xWindow, RevertToPointerRoot, CurrentTime);
XFlush(xDisplay);
@@ -321,16 +321,16 @@ public:
if (yesNo && fFirstInit)
setSize(static_cast<unsigned int>(fView->width), static_cast<unsigned int>(fView->height), true);

#if defined(DGL_OS_WINDOWS)
#if defined(DISTRHO_OS_WINDOWS)
if (yesNo)
ShowWindow(hwnd, fFirstInit ? SW_SHOWNORMAL : SW_RESTORE);
else
ShowWindow(hwnd, SW_HIDE);

UpdateWindow(hwnd);
#elif defined(DGL_OS_MAC)
#elif defined(DISTRHO_OS_MAC)
puglImplSetVisible(fView, yesNo);
#elif defined(DGL_OS_LINUX)
#elif defined(DISTRHO_OS_LINUX)
if (yesNo)
XMapRaised(xDisplay, xWindow);
else
@@ -414,7 +414,7 @@ public:

DBGp("Window setSize called %s, size %i %i\n", forced ? "(forced)" : "(not forced)", width, height);

#if defined(DGL_OS_WINDOWS)
#if defined(DISTRHO_OS_WINDOWS)
int winFlags = WS_POPUPWINDOW | WS_CAPTION;

if (fResizable)
@@ -427,9 +427,9 @@ public:

if (! forced)
UpdateWindow(hwnd);
#elif defined(DGL_OS_MAC)
#elif defined(DISTRHO_OS_MAC)
puglImplSetSize(fView, width, height, forced);
#elif defined(DGL_OS_LINUX)
#elif defined(DISTRHO_OS_LINUX)
XResizeWindow(xDisplay, xWindow, width, height);

if (! fResizable)
@@ -461,19 +461,19 @@ public:
{
DBGp("Window setTitle \"%s\"\n", title);

#if defined(DGL_OS_WINDOWS)
#if defined(DISTRHO_OS_WINDOWS)
SetWindowTextA(hwnd, title);
#elif defined(DGL_OS_MAC)
#elif defined(DISTRHO_OS_MAC)
puglImplSetTitle(fView, title);
#elif defined(DGL_OS_LINUX)
#elif defined(DISTRHO_OS_LINUX)
XStoreName(xDisplay, xWindow, title);
#endif
}

void setTransientWinId(const intptr_t winId)
{
#if defined(DGL_OS_LINUX)
XSetTransientForHint(xDisplay, xWindow, static_cast<::Window>(winId));
#if defined(DISTRHO_OS_LINUX)
XSetTransientForHint(xDisplay, xWindow, static_cast< ::Window>(winId));
#else
return;
// unused
@@ -519,7 +519,7 @@ public:
{
puglProcessEvents(fView);

#ifdef DGL_OS_MAC
#ifdef DISTRHO_OS_MAC
if (fNeedsIdle)
puglImplIdle(fView);
#endif
@@ -544,7 +544,7 @@ public:
fModal.enabled = true;
fModal.parent->fModal.childFocus = this;

#ifdef DGL_OS_WINDOWS
#ifdef DISTRHO_OS_WINDOWS
// Center this window
PuglInternals* const parentImpl = fModal.parent->fView->impl;

@@ -741,12 +741,12 @@ private:
}
} fModal;

#if defined(DGL_OS_WINDOWS)
#if defined(DISTRHO_OS_WINDOWS)
HWND hwnd;
#elif defined(DGL_OS_LINUX)
#elif defined(DISTRHO_OS_LINUX)
Display* xDisplay;
::Window xWindow;
#elif defined(DGL_OS_MAC)
#elif defined(DISTRHO_OS_MAC)
bool fNeedsIdle;
#else
char _dummy;


+ 58
- 9
source/modules/distrho/DistrhoPlugin.hpp View File

@@ -17,10 +17,17 @@
#ifndef DISTRHO_PLUGIN_HPP_INCLUDED
#define DISTRHO_PLUGIN_HPP_INCLUDED

#include "DistrhoUtils.hpp"
#include "extra/d_string.hpp"
#include "src/DistrhoPluginChecks.h"

#include <cmath>

#ifdef PROPER_CPP11_SUPPORT
# include <cstdint>
#else
# include <stdint.h>
#endif

#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
@@ -63,34 +70,74 @@ struct ParameterRanges {
max = 1.0f;
}

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

/*!
* Fix a value within range.
*/
void fixValue(float& value) const noexcept
{
if (value < min)
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)
if (value <= min)
return min;
else if (value > max)
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 newValue((value - min) / (max - min));
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.
*/
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 (newValue <= 0.0f)
if (normValue <= 0.0f)
return 0.0f;
if (newValue >= 1.0f)
if (normValue >= 1.0f)
return 1.0f;
return newValue;

return normValue;
}

/*!
* Get a proper value previously normalized to 0.0<->1.0.
*/
float getUnnormalizedValue(const float& value) const noexcept
{
return value * (max - min) + min;
@@ -107,7 +154,7 @@ struct Parameter {
d_string unit;
ParameterRanges ranges;

Parameter()
Parameter() noexcept
: hints(0x0) {}

void clear() noexcept
@@ -255,6 +302,8 @@ private:
struct PrivateData;
PrivateData* const pData;
friend class PluginExporter;

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Plugin)
};

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


+ 9
- 6
source/modules/distrho/DistrhoUI.hpp View File

@@ -17,7 +17,8 @@
#ifndef DISTRHO_UI_HPP_INCLUDED
#define DISTRHO_UI_HPP_INCLUDED

#include "DistrhoUtils.hpp"
#include "extra/d_leakdetector.hpp"
#include "src/DistrhoPluginChecks.h"

#include "../dgl/Widget.hpp"

@@ -48,15 +49,15 @@ public:
// -------------------------------------------------------------------
// Host UI State

void d_uiResize(unsigned int width, unsigned int height);
void d_uiResize(uint width, uint height);

protected:
// -------------------------------------------------------------------
// Basic Information

virtual const char* d_getName() const noexcept { return DISTRHO_PLUGIN_NAME; }
virtual unsigned int d_getWidth() const noexcept = 0;
virtual unsigned int d_getHeight() const noexcept = 0;
virtual const char* d_getName() const noexcept { return DISTRHO_PLUGIN_NAME; }
virtual uint d_getWidth() const noexcept = 0;
virtual uint d_getHeight() const noexcept = 0;

// -------------------------------------------------------------------
// DSP Callbacks
@@ -78,7 +79,7 @@ protected:
// -------------------------------------------------------------------
// Direct DSP access - DO NOT USE THIS UNLESS STRICTLY NECESSARY!!

void* d_getPluginInstancePointer();
void* d_getPluginInstancePointer() const noexcept;
#endif

// -------------------------------------------------------------------
@@ -87,6 +88,8 @@ private:
struct PrivateData;
PrivateData* const pData;
friend class UIExporter;

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UI)
};

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


+ 60
- 577
source/modules/distrho/DistrhoUtils.hpp View File

@@ -19,7 +19,6 @@

#include "src/DistrhoDefines.h"

#include <cassert>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
@@ -59,11 +58,14 @@ inline float
// misc functions

static inline
long d_cconst(int a, int b, int c, int d) noexcept
long d_cconst(const int a, const int b, const int c, const int d) noexcept
{
return (a << 24) | (b << 16) | (c << 8) | (d << 0);
}

static inline
void d_pass() noexcept {}

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

@@ -71,616 +73,97 @@ long d_cconst(int a, int b, int c, int d) noexcept
# define d_debug(...)
#else
static inline
void d_debug(const char* const fmt, ...)
void d_debug(const char* const fmt, ...) noexcept
{
va_list args;
va_start(args, fmt);
std::fprintf(stdout, "\x1b[30;1m");
std::vfprintf(stdout, fmt, args);
std::fprintf(stdout, "\x1b[0m\n");
va_end(args);
try {
::va_list args;
::va_start(args, fmt);
std::fprintf(stdout, "\x1b[30;1m");
std::vfprintf(stdout, fmt, args);
std::fprintf(stdout, "\x1b[0m\n");
::va_end(args);
} catch (...) {}
}
#endif

static inline
void d_stdout(const char* const fmt, ...)
void d_stdout(const char* const fmt, ...) noexcept
{
va_list args;
va_start(args, fmt);
std::vfprintf(stdout, fmt, args);
std::fprintf(stdout, "\n");
va_end(args);
try {
::va_list args;
::va_start(args, fmt);
std::vfprintf(stdout, fmt, args);
std::fprintf(stdout, "\n");
::va_end(args);
} catch (...) {}
}

static inline
void d_stderr(const char* const fmt, ...)
void d_stderr(const char* const fmt, ...) noexcept
{
va_list args;
va_start(args, fmt);
std::vfprintf(stderr, fmt, args);
std::fprintf(stderr, "\n");
va_end(args);
try {
::va_list args;
::va_start(args, fmt);
std::vfprintf(stderr, fmt, args);
std::fprintf(stderr, "\n");
::va_end(args);
} catch (...) {}
}

static inline
void d_stderr2(const char* const fmt, ...)
void d_stderr2(const char* const fmt, ...) noexcept
{
va_list args;
va_start(args, fmt);
std::fprintf(stderr, "\x1b[31m");
std::vfprintf(stderr, fmt, args);
std::fprintf(stderr, "\x1b[0m\n");
va_end(args);
try {
::va_list args;
::va_start(args, fmt);
std::fprintf(stderr, "\x1b[31m");
std::vfprintf(stderr, fmt, args);
std::fprintf(stderr, "\x1b[0m\n");
::va_end(args);
} catch (...) {}
}

// -----------------------------------------------------------------------
// d_*sleep

static inline
void d_sleep(unsigned int secs)
void d_safe_assert(const char* const assertion, const char* const file, const int line) noexcept
{
#ifdef DISTRHO_OS_WINDOWS
Sleep(secs * 1000);
#else
sleep(secs);
#endif
d_stderr2("assertion failure: \"%s\" in file %s, line %i", assertion, file, line);
}

static inline
void d_msleep(unsigned int msecs)
void d_safe_exception(const char* const exception, const char* const file, const int line) noexcept
{
#ifdef DISTRHO_OS_WINDOWS
Sleep(msecs);
#else
usleep(msecs * 1000);
#endif
d_stderr2("exception caught: \"%s\" in file %s, line %i", exception, file, line);
}

// -----------------------------------------------------------------------
// d_string class
// d_*sleep

class d_string
static inline
void d_sleep(const uint secs)
{
public:
// -------------------------------------------------------------------
// constructors (no explicit conversions allowed)

/*
* Empty string.
*/
explicit d_string()
{
_init();
_dup(nullptr);
}

/*
* Simple character.
*/
explicit d_string(const char c)
{
char ch[2];
ch[0] = c;
ch[1] = '\0';

_init();
_dup(ch);
}

/*
* Simple char string.
*/
explicit d_string(char* const strBuf)
{
_init();
_dup(strBuf);
}

/*
* Simple const char string.
*/
explicit d_string(const char* const strBuf)
{
_init();
_dup(strBuf);
}

/*
* Integer.
*/
explicit d_string(const int value)
{
char strBuf[0xff+1];
std::memset(strBuf, 0, (0xff+1)*sizeof(char));
std::snprintf(strBuf, 0xff, "%d", value);

_init();
_dup(strBuf);
}

/*
* Unsigned integer, possibly in hexadecimal.
*/
explicit d_string(const unsigned int value, const bool hexadecimal = false)
{
char strBuf[0xff+1];
std::memset(strBuf, 0, (0xff+1)*sizeof(char));
std::snprintf(strBuf, 0xff, hexadecimal ? "0x%x" : "%u", value);

_init();
_dup(strBuf);
}

/*
* Long integer.
*/
explicit d_string(const long int value)
{
char strBuf[0xff+1];
std::memset(strBuf, 0, (0xff+1)*sizeof(char));
std::snprintf(strBuf, 0xff, "%ld", value);

_init();
_dup(strBuf);
}

/*
* Long unsigned integer, possibly hexadecimal.
*/
explicit d_string(const unsigned long int value, const bool hexadecimal = false)
{
char strBuf[0xff+1];
std::memset(strBuf, 0, (0xff+1)*sizeof(char));
std::snprintf(strBuf, 0xff, hexadecimal ? "0x%lx" : "%lu", value);

_init();
_dup(strBuf);
}

/*
* Single-precision floating point number.
*/
explicit d_string(const float value)
{
char strBuf[0xff+1];
std::memset(strBuf, 0, (0xff+1)*sizeof(char));
std::snprintf(strBuf, 0xff, "%f", value);

_init();
_dup(strBuf);
}
DISTRHO_SAFE_ASSERT_RETURN(secs > 0,);

/*
* Double-precision floating point number.
*/
explicit d_string(const double value)
{
char strBuf[0xff+1];
std::memset(strBuf, 0, (0xff+1)*sizeof(char));
std::snprintf(strBuf, 0xff, "%g", value);

_init();
_dup(strBuf);
}

// -------------------------------------------------------------------
// non-explicit constructor

/*
* Create string from another string.
*/
d_string(const d_string& str)
{
_init();
_dup(str.fBuffer);
}

// -------------------------------------------------------------------
// destructor

/*
* Destructor.
*/
~d_string()
{
assert(fBuffer != nullptr);

delete[] fBuffer;
fBuffer = nullptr;
}

// -------------------------------------------------------------------
// public methods

/*
* Get length of the string.
*/
size_t length() const noexcept
{
return fBufferLen;
}

/*
* Check if the string is empty.
*/
bool isEmpty() const noexcept
{
return (fBufferLen == 0);
}

/*
* Check if the string is not empty.
*/
bool isNotEmpty() const noexcept
{
return (fBufferLen != 0);
}

/*
* Check if the string contains another string, optionally ignoring case.
*/
bool contains(const char* const strBuf, const bool ignoreCase = false) const
{
if (strBuf == nullptr)
return false;

if (ignoreCase)
{
#ifdef __USE_GNU
return (strcasestr(fBuffer, strBuf) != nullptr);
try {
#ifdef DISTRHO_OS_WINDOWS
::Sleep(secs * 1000);
#else
d_string tmp1(fBuffer), tmp2(strBuf);
tmp1.toLower();
tmp2.toLower();
return (std::strstr((const char*)tmp1, (const char*)tmp2) != nullptr);
::sleep(secs);
#endif
}

return (std::strstr(fBuffer, strBuf) != nullptr);
}

/*
* Overloaded function.
*/
bool contains(const d_string& str, const bool ignoreCase = false) const
{
return contains(str.fBuffer, ignoreCase);
}

/*
* Check if character at 'pos' is a digit.
*/
bool isDigit(const size_t pos) const noexcept
{
if (pos >= fBufferLen)
return false;

return (fBuffer[pos] >= '0' && fBuffer[pos] <= '9');
}

/*
* Check if the string starts with the character 'c'.
*/
bool startsWith(const char c) const
{
if (c == '\0')
return false;

return (fBufferLen > 0 && fBuffer[0] == c);
}

/*
* Check if the string starts with the string 'prefix'.
*/
bool startsWith(const char* const prefix) const
{
if (prefix == nullptr)
return false;

const size_t prefixLen(std::strlen(prefix));

if (fBufferLen < prefixLen)
return false;

return (std::strncmp(fBuffer + (fBufferLen-prefixLen), prefix, prefixLen) == 0);
}

/*
* Check if the string ends with the character 'c'.
*/
bool endsWith(const char c) const
{
if (c == '\0')
return false;

return (fBufferLen > 0 && fBuffer[fBufferLen] == c);
}

/*
* Check if the string ends with the string 'suffix'.
*/
bool endsWith(const char* const suffix) const
{
if (suffix == nullptr)
return false;

const size_t suffixLen(std::strlen(suffix));

if (fBufferLen < suffixLen)
return false;

return (std::strncmp(fBuffer + (fBufferLen-suffixLen), suffix, suffixLen) == 0);
}

/*
* Clear the string.
*/
void clear() noexcept
{
truncate(0);
}

/*
* Replace all occurrences of character 'before' with character 'after'.
*/
void replace(const char before, const char after) noexcept
{
if (before == '\0' || after == '\0')
return;

for (size_t i=0; i < fBufferLen; ++i)
{
if (fBuffer[i] == before)
fBuffer[i] = after;
else if (fBuffer[i] == '\0')
break;
}
}

/*
* Truncate the string to size 'n'.
*/
void truncate(const size_t n) noexcept
{
if (n >= fBufferLen)
return;

for (size_t i=n; i < fBufferLen; ++i)
fBuffer[i] = '\0';

fBufferLen = n;
}

/*
* Convert all non-basic characters to '_'.
*/
void toBasic() noexcept
{
for (size_t i=0; i < fBufferLen; ++i)
{
if (fBuffer[i] >= '0' && fBuffer[i] <= '9')
continue;
if (fBuffer[i] >= 'A' && fBuffer[i] <= 'Z')
continue;
if (fBuffer[i] >= 'a' && fBuffer[i] <= 'z')
continue;
if (fBuffer[i] == '_')
continue;

fBuffer[i] = '_';
}
}

/*
* Convert to all ascii characters to lowercase.
*/
void toLower() noexcept
{
static const char kCharDiff('a' - 'A');

for (size_t i=0; i < fBufferLen; ++i)
{
if (fBuffer[i] >= 'A' && fBuffer[i] <= 'Z')
fBuffer[i] += kCharDiff;
}
}

/*
* Convert to all ascii characters to uppercase.
*/
void toUpper() noexcept
{
static const char kCharDiff('a' - 'A');

for (size_t i=0; i < fBufferLen; ++i)
{
if (fBuffer[i] >= 'a' && fBuffer[i] <= 'z')
fBuffer[i] -= kCharDiff;
}
}

// -------------------------------------------------------------------
// public operators

operator const char*() const noexcept
{
return fBuffer;
}

char& operator[](const size_t pos) const noexcept
{
return fBuffer[pos];
}

bool operator==(const char* const strBuf) const
{
return (strBuf != nullptr && std::strcmp(fBuffer, strBuf) == 0);
}

bool operator==(const d_string& str) const
{
return operator==(str.fBuffer);
}

bool operator!=(const char* const strBuf) const
{
return !operator==(strBuf);
}

bool operator!=(const d_string& str) const
{
return !operator==(str.fBuffer);
}

d_string& operator=(const char* const strBuf)
{
_dup(strBuf);

return *this;
}

d_string& operator=(const d_string& str)
{
return operator=(str.fBuffer);
}

d_string& operator+=(const char* const strBuf)
{
if (strBuf == nullptr)
return *this;

const size_t newBufSize = fBufferLen + std::strlen(strBuf) + 1;
char newBuf[newBufSize];

std::strcpy(newBuf, fBuffer);
std::strcat(newBuf, strBuf);

_dup(newBuf, newBufSize-1);

return *this;
}

d_string& operator+=(const d_string& str)
{
return operator+=(str.fBuffer);
}

d_string operator+(const char* const strBuf)
{
const size_t newBufSize = fBufferLen + ((strBuf != nullptr) ? std::strlen(strBuf) : 0) + 1;
char newBuf[newBufSize];

std::strcpy(newBuf, fBuffer);

if (strBuf != nullptr)
std::strcat(newBuf, strBuf);

return d_string(newBuf);
}

d_string operator+(const d_string& str)
{
return operator+(str.fBuffer);
}

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

private:
char* fBuffer; // the actual string buffer
size_t fBufferLen; // string length
bool fFirstInit; // true when first initiated

/*
* Shared init function.
* Called on all constructors.
*/
void _init() noexcept
{
fBuffer = nullptr;
fBufferLen = 0;
fFirstInit = true;
}

/*
* Helper function.
* Called whenever the string needs to be allocated.
*
* Notes:
* - Allocates string only if first initiated, or if 'strBuf' is not null and new string contents are different
* - If 'strBuf' is null 'size' must be 0
*/
void _dup(const char* const strBuf, const size_t size = 0)
{
if (strBuf != nullptr)
{
// don't recreate string if contents match
if (fFirstInit || std::strcmp(fBuffer, strBuf) != 0)
{
if (! fFirstInit)
{
assert(fBuffer != nullptr);
delete[] fBuffer;
}

fBufferLen = (size > 0) ? size : std::strlen(strBuf);
fBuffer = new char[fBufferLen+1];

std::strcpy(fBuffer, strBuf);

fBuffer[fBufferLen] = '\0';

fFirstInit = false;
}
}
else
{
assert(size == 0);

// don't recreate null string
if (fFirstInit || fBufferLen != 0)
{
if (! fFirstInit)
{
assert(fBuffer != nullptr);
delete[] fBuffer;
}

fBufferLen = 0;
fBuffer = new char[1];
fBuffer[0] = '\0';

fFirstInit = false;
}
}
}
};

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

static inline
d_string operator+(const d_string& strBefore, const char* const strBufAfter)
{
const char* const strBufBefore = (const char*)strBefore;
const size_t newBufSize = strBefore.length() + ((strBufAfter != nullptr) ? std::strlen(strBufAfter) : 0) + 1;
char newBuf[newBufSize];

std::strcpy(newBuf, strBufBefore);
std::strcat(newBuf, strBufAfter);

return d_string(newBuf);
} DISTRHO_SAFE_EXCEPTION("carla_sleep");
}

static inline
d_string operator+(const char* const strBufBefore, const d_string& strAfter)
void d_msleep(const uint msecs)
{
const char* const strBufAfter = (const char*)strAfter;
const size_t newBufSize = ((strBufBefore != nullptr) ? std::strlen(strBufBefore) : 0) + strAfter.length() + 1;
char newBuf[newBufSize];

std::strcpy(newBuf, strBufBefore);
std::strcat(newBuf, strBufAfter);
DISTRHO_SAFE_ASSERT_RETURN(msecs > 0,);

return d_string(newBuf);
try {
#ifdef DISTRHO_OS_WINDOWS
::Sleep(msecs);
#else
::usleep(msecs * 1000);
#endif
} DISTRHO_SAFE_EXCEPTION("carla_msleep");
}

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


+ 58
- 43
source/modules/distrho/src/DistrhoDefines.h View File

@@ -17,48 +17,6 @@
#ifndef DISTRHO_DEFINES_H_INCLUDED
#define DISTRHO_DEFINES_H_INCLUDED

#include "DistrhoPluginInfo.h"

#ifndef DISTRHO_PLUGIN_NAME
# error DISTRHO_PLUGIN_NAME undefined!
#endif

#ifndef DISTRHO_PLUGIN_HAS_UI
# error DISTRHO_PLUGIN_HAS_UI undefined!
#endif

#ifndef DISTRHO_PLUGIN_IS_SYNTH
# error DISTRHO_PLUGIN_IS_SYNTH undefined!
#endif

#ifndef DISTRHO_PLUGIN_NUM_INPUTS
# error DISTRHO_PLUGIN_NUM_INPUTS undefined!
#endif

#ifndef DISTRHO_PLUGIN_NUM_OUTPUTS
# error DISTRHO_PLUGIN_NUM_OUTPUTS undefined!
#endif

#ifndef DISTRHO_PLUGIN_WANT_LATENCY
# error DISTRHO_PLUGIN_WANT_LATENCY undefined!
#endif

#ifndef DISTRHO_PLUGIN_WANT_PROGRAMS
# error DISTRHO_PLUGIN_WANT_PROGRAMS undefined!
#endif

#ifndef DISTRHO_PLUGIN_WANT_STATE
# error DISTRHO_PLUGIN_WANT_STATE undefined!
#endif

#ifndef DISTRHO_PLUGIN_WANT_TIMEPOS
# error DISTRHO_PLUGIN_WANT_TIMEPOS undefined!
#endif

#ifndef DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
# define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 0
#endif

/* Compatibility with non-clang compilers */
#ifndef __has_feature
# define __has_feature(x) 0
@@ -108,6 +66,59 @@
# define nullptr (0)
#endif

/* Define DISTRHO_SAFE_ASSERT* */
#define DISTRHO_SAFE_ASSERT(cond) if (cond) d_pass(); else d_safe_assert(#cond, __FILE__, __LINE__);
#define DISTRHO_SAFE_ASSERT_BREAK(cond) if (cond) d_pass(); else { d_safe_assert(#cond, __FILE__, __LINE__); break; }
#define DISTRHO_SAFE_ASSERT_CONTINUE(cond) if (cond) d_pass(); else { d_safe_assert(#cond, __FILE__, __LINE__); continue; }
#define DISTRHO_SAFE_ASSERT_RETURN(cond, ret) if (cond) d_pass(); else { d_safe_assert(#cond, __FILE__, __LINE__); return ret; }

/* Define DISTRHO_SAFE_EXCEPTION */
#define DISTRHO_SAFE_EXCEPTION(msg) catch(...) { d_safe_exception(msg, __FILE__, __LINE__); }
#define DISTRHO_SAFE_EXCEPTION_BREAK(msg) catch(...) { d_safe_exception(msg, __FILE__, __LINE__); break; }
#define DISTRHO_SAFE_EXCEPTION_CONTINUE(msg) catch(...) { d_safe_exception(msg, __FILE__, __LINE__); continue; }
#define DISTRHO_SAFE_EXCEPTION_RETURN(msg, ret) catch(...) { d_safe_exception(msg, __FILE__, __LINE__); return ret; }

/* Define DISTRHO_DECLARE_NON_COPY_CLASS */
#ifdef DISTRHO_PROPER_CPP11_SUPPORT
# define DISTRHO_DECLARE_NON_COPY_CLASS(ClassName) \
private: \
ClassName(ClassName&) = delete; \
ClassName(const ClassName&) = delete; \
ClassName& operator=(ClassName&) = delete ; \
ClassName& operator=(const ClassName&) = delete;
#else
# define DISTRHO_DECLARE_NON_COPY_CLASS(ClassName) \
private: \
ClassName(ClassName&); \
ClassName(const ClassName&); \
ClassName& operator=(ClassName&); \
ClassName& operator=(const ClassName&);
#endif

/* Define DISTRHO_DECLARE_NON_COPY_STRUCT */
#ifdef DISTRHO_PROPER_CPP11_SUPPORT
# define DISTRHO_DECLARE_NON_COPY_STRUCT(StructName) \
StructName(StructName&) = delete; \
StructName(const StructName&) = delete; \
StructName& operator=(StructName&) = delete; \
StructName& operator=(const StructName&) = delete;
#else
# define DISTRHO_DECLARE_NON_COPY_STRUCT(StructName)
#endif

/* Define DISTRHO_PREVENT_HEAP_ALLOCATION */
#ifdef DISTRHO_PROPER_CPP11_SUPPORT
# define DISTRHO_PREVENT_HEAP_ALLOCATION \
private: \
static void* operator new(size_t) = delete; \
static void operator delete(void*) = delete;
#else
# define DISTRHO_PREVENT_HEAP_ALLOCATION \
private: \
static void* operator new(size_t); \
static void operator delete(void*);
#endif

/* Define namespace */
#ifndef DISTRHO_NO_NAMESPACE
# ifndef DISTRHO_NAMESPACE
@@ -122,6 +133,10 @@
# define USE_NAMESPACE_DISTRHO
#endif

#define DISTRHO_UI_URI DISTRHO_PLUGIN_URI "#UI"
/* Useful typedefs */
typedef unsigned char uchar;
typedef unsigned long int ulong;
typedef unsigned short int ushort;
typedef unsigned int uint;

#endif // DISTRHO_DEFINES_H_INCLUDED

+ 2
- 2
source/modules/distrho/src/DistrhoPluginCarla.cpp View File

@@ -110,7 +110,7 @@ protected:
// TODO
}

void handleUiResize(const unsigned int width, const unsigned int height)
void handleUiResize(const uint width, const uint height)
{
fUI.setSize(width, height);
}
@@ -154,7 +154,7 @@ private:
}
#endif

static void uiResizeCallback(void* ptr, unsigned int width, unsigned int height)
static void uiResizeCallback(void* ptr, uint width, uint height)
{
handlePtr->handleUiResize(width, height);
}


+ 118
- 81
source/modules/distrho/src/DistrhoPluginInternal.hpp View File

@@ -77,11 +77,11 @@ struct Plugin::PrivateData {
bufferSize(d_lastBufferSize),
sampleRate(d_lastSampleRate)
{
assert(bufferSize != 0);
assert(sampleRate != 0.0);
DISTRHO_SAFE_ASSERT(bufferSize != 0);
DISTRHO_SAFE_ASSERT(sampleRate != 0.0);
}

~PrivateData()
~PrivateData() noexcept
{
if (parameters != nullptr)
{
@@ -117,10 +117,8 @@ public:
: fPlugin(createPlugin()),
fData((fPlugin != nullptr) ? fPlugin->pData : nullptr)
{
assert(fPlugin != nullptr);

if (fPlugin == nullptr)
return;
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);

for (uint32_t i=0, count=fData->parameterCount; i < count; ++i)
fPlugin->d_initParameter(i, fData->parameters[i]);
@@ -145,32 +143,44 @@ public:

const char* getName() const noexcept
{
return (fPlugin != nullptr) ? fPlugin->d_getName() : "";
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, "");

return fPlugin->d_getName();
}

const char* getLabel() const noexcept
{
return (fPlugin != nullptr) ? fPlugin->d_getLabel() : "";
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, "");

return fPlugin->d_getLabel();
}

const char* getMaker() const noexcept
{
return (fPlugin != nullptr) ? fPlugin->d_getMaker() : "";
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, "");

return fPlugin->d_getMaker();
}

const char* getLicense() const noexcept
{
return (fPlugin != nullptr) ? fPlugin->d_getLicense() : "";
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, "");

return fPlugin->d_getLicense();
}

uint32_t getVersion() const noexcept
{
return (fPlugin != nullptr) ? fPlugin->d_getVersion() : 1000;
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0);

return fPlugin->d_getVersion();
}

long getUniqueId() const noexcept
{
return (fPlugin != nullptr) ? fPlugin->d_getUniqueId() : 0;
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0);

return fPlugin->d_getUniqueId();
}

void* getInstancePointer() const noexcept
@@ -183,19 +193,24 @@ public:
#if DISTRHO_PLUGIN_WANT_LATENCY
uint32_t getLatency() const noexcept
{
return (fData != nullptr) ? fData->latency : 0;
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);

return fData->latency;
}
#endif

uint32_t getParameterCount() const noexcept
{
return (fData != nullptr) ? fData->parameterCount : 0;
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);

return fData->parameterCount;
}

uint32_t getParameterHints(const uint32_t index) const noexcept
{
assert(index < fData->parameterCount);
return (fData != nullptr && index < fData->parameterCount) ? fData->parameters[index].hints : 0x0;
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, 0x0);

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

bool isParameterOutput(const uint32_t index) const noexcept
@@ -205,100 +220,117 @@ public:

const d_string& getParameterName(const uint32_t index) const noexcept
{
assert(index < fData->parameterCount);
return (fData != nullptr && index < fData->parameterCount) ? fData->parameters[index].name : sFallbackString;
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString);

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

const d_string& getParameterSymbol(const uint32_t index) const noexcept
{
assert(index < fData->parameterCount);
return (fData != nullptr && index < fData->parameterCount) ? fData->parameters[index].symbol : sFallbackString;
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString);

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

const d_string& getParameterUnit(const uint32_t index) const noexcept
{
assert(index < fData->parameterCount);
return (fData != nullptr && index < fData->parameterCount) ? fData->parameters[index].unit : sFallbackString;
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString);

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

const ParameterRanges& getParameterRanges(const uint32_t index) const noexcept
{
assert(index < fData->parameterCount);
return (fData != nullptr && index < fData->parameterCount) ? fData->parameters[index].ranges : sFallbackRanges;
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackRanges);

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

float getParameterValue(const uint32_t index) const noexcept
float getParameterValue(const uint32_t index) const
{
assert(index < fData->parameterCount);
return (fPlugin != nullptr && index < fData->parameterCount) ? fPlugin->d_getParameterValue(index) : 0.0f;
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0.0f);
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, 0.0f);

return fPlugin->d_getParameterValue(index);
}

void setParameterValue(const uint32_t index, const float value)
{
assert(index < fData->parameterCount);
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount,);

if (fPlugin != nullptr && index < fData->parameterCount)
fPlugin->d_setParameterValue(index, value);
fPlugin->d_setParameterValue(index, value);
}

#if DISTRHO_PLUGIN_WANT_PROGRAMS
uint32_t getProgramCount() const noexcept
{
return (fData != nullptr) ? fData->programCount : 0;
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);

return fData->programCount;
}

const d_string& getProgramName(const uint32_t index) const noexcept
{
assert(index < fData->programCount);
return (fData != nullptr && index < fData->programCount) ? fData->programNames[index] : sFallbackString;
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->programCount, sFallbackString);

return fData->programNames[index];
}

void setProgram(const uint32_t index)
{
assert(index < fData->programCount);
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->programCount,);

if (fPlugin != nullptr && index < fData->programCount)
fPlugin->d_setProgram(index);
fPlugin->d_setProgram(index);
}
#endif

#if DISTRHO_PLUGIN_WANT_STATE
bool wantsStateKey(const char* const key) const noexcept
uint32_t getStateCount() const noexcept
{
for (uint32_t i=0; i < fData->stateCount; ++i)
{
if (fData->stateKeys[i] == key)
return true;
}
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);

return false;
return fData->stateCount;
}

uint32_t getStateCount() const noexcept
const d_string& getStateKey(const uint32_t index) const noexcept
{
return fData != nullptr ? fData->stateCount : 0;
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->stateCount, sFallbackString);

return fData->stateKeys[index];
}

const d_string& getStateKey(const uint32_t index) const noexcept
void setState(const char* const key, const char* const value)
{
assert(index < fData->stateCount);
return (fData != nullptr && index < fData->stateCount) ? fData->stateKeys[index] : sFallbackString;
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
DISTRHO_SAFE_ASSERT_RETURN(value != nullptr,);

fPlugin->d_setState(key, value);
}

void setState(const char* const key, const char* const value)
bool wantStateKey(const char* const key) const noexcept
{
assert(key != nullptr && value != nullptr);
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, false);
DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', false);

if (fPlugin != nullptr && key != nullptr && value != nullptr)
fPlugin->d_setState(key, value);
for (uint32_t i=0; i < fData->stateCount; ++i)
{
if (fData->stateKeys[i] == key)
return true;
}

return false;
}
#endif

#if DISTRHO_PLUGIN_WANT_TIMEPOS
void setTimePos(const TimePos& timePos)
void setTimePos(const TimePos& timePos) noexcept
{
if (fData != nullptr)
std::memcpy(&fData->timePos, &timePos, sizeof(TimePos));
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);

std::memcpy(&fData->timePos, &timePos, sizeof(TimePos));
}
#endif

@@ -306,44 +338,47 @@ public:

void activate()
{
if (fPlugin != nullptr)
fPlugin->d_activate();
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);

fPlugin->d_activate();
}

void deactivate()
{
if (fPlugin != nullptr)
fPlugin->d_deactivate();
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);

fPlugin->d_deactivate();
}

#if DISTRHO_PLUGIN_IS_SYNTH
void run(float** const inputs, float** const outputs, const uint32_t frames, const MidiEvent* const midiEvents, const uint32_t midiEventCount)
{
if (fPlugin != nullptr)
fPlugin->d_run(inputs, outputs, frames, midiEvents, midiEventCount);
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);

fPlugin->d_run(inputs, outputs, frames, midiEvents, midiEventCount);
}
#else
void run(float** const inputs, float** const outputs, const uint32_t frames)
{
if (fPlugin != nullptr)
fPlugin->d_run(inputs, outputs, frames);
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);

fPlugin->d_run(inputs, outputs, frames);
}
#endif
// -------------------------------------------------------------------

void setBufferSize(const uint32_t bufferSize, bool doCallback = false)
{
assert(bufferSize >= 2);
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
DISTRHO_SAFE_ASSERT(bufferSize >= 2);

if (fData != nullptr)
{
if (doCallback && fData->bufferSize == bufferSize)
doCallback = false;
if (fData->bufferSize == bufferSize)
return;

fData->bufferSize = bufferSize;
}
fData->bufferSize = bufferSize;

if (fPlugin != nullptr && doCallback)
if (doCallback)
{
fPlugin->d_deactivate();
fPlugin->d_bufferSizeChanged(bufferSize);
@@ -353,17 +388,16 @@ public:

void setSampleRate(const double sampleRate, bool doCallback = false)
{
assert(sampleRate > 0.0);
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
DISTRHO_SAFE_ASSERT(sampleRate > 0.0);

if (fData != nullptr)
{
if (doCallback && fData->sampleRate == sampleRate)
doCallback = false;
if (fData->sampleRate == sampleRate)
return;

fData->sampleRate = sampleRate;
}
fData->sampleRate = sampleRate;

if (fPlugin != nullptr && doCallback)
if (doCallback)
{
fPlugin->d_deactivate();
fPlugin->d_sampleRateChanged(sampleRate);
@@ -373,7 +407,7 @@ public:

private:
// -------------------------------------------------------------------
// private members accessed by DistrhoPlugin class
// private members accessed by DistrhoPlugin classes

Plugin* const fPlugin;
Plugin::PrivateData* const fData;
@@ -383,6 +417,9 @@ private:

static const d_string sFallbackString;
static const ParameterRanges sFallbackRanges;

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginExporter)
DISTRHO_PREVENT_HEAP_ALLOCATION
};

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


+ 37
- 34
source/modules/distrho/src/DistrhoPluginLADSPA+DSSI.cpp View File

@@ -57,9 +57,8 @@ public:
fPortAudioOuts = nullptr;
#endif

if (const uint32_t count = fPlugin.getParameterCount())
{
const uint32_t count(fPlugin.getParameterCount());

fPortControls = new LADSPA_Data*[count];
fLastControlValues = new LADSPA_Data[count];

@@ -69,13 +68,18 @@ public:
fLastControlValues[i] = fPlugin.getParameterValue(i);
}
}
else
{
fPortControls = nullptr;
fLastControlValues = nullptr;
}

#if DISTRHO_PLUGIN_WANT_LATENCY
fPortLatency = nullptr;
#endif
}

~PluginLadspaDssi()
~PluginLadspaDssi() noexcept
{
if (fPortControls != nullptr)
{
@@ -83,7 +87,7 @@ public:
fPortControls = nullptr;
}

if (fLastControlValues)
if (fLastControlValues != nullptr)
{
delete[] fLastControlValues;
fLastControlValues = nullptr;
@@ -104,12 +108,12 @@ public:

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

void ladspa_connect_port(const unsigned long port, LADSPA_Data* const dataLocation)
void ladspa_connect_port(const ulong port, LADSPA_Data* const dataLocation) noexcept
{
unsigned long index = 0;
ulong index = 0;

#if DISTRHO_PLUGIN_NUM_INPUTS > 0
for (unsigned long i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i)
for (ulong i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i)
{
if (port == index++)
{
@@ -120,7 +124,7 @@ public:
#endif

#if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
for (unsigned long i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i)
for (ulong i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i)
{
if (port == index++)
{
@@ -138,7 +142,7 @@ public:
}
#endif

for (unsigned long i=0, count=fPlugin.getParameterCount(); i < count; ++i)
for (ulong i=0, count=fPlugin.getParameterCount(); i < count; ++i)
{
if (port == index++)
{
@@ -151,14 +155,14 @@ public:
// -------------------------------------------------------------------

#ifdef DISTRHO_PLUGIN_TARGET_DSSI
void ladspa_run(const unsigned long sampleCount)
void ladspa_run(const ulong sampleCount)
{
dssi_run_synth(sampleCount, nullptr, 0);
}

void dssi_run_synth(const unsigned long sampleCount, snd_seq_event_t* const events, const unsigned long eventCount)
void dssi_run_synth(const ulong sampleCount, snd_seq_event_t* const events, const ulong eventCount)
#else
void ladspa_run(const unsigned long sampleCount)
void ladspa_run(const ulong sampleCount)
#endif
{
// pre-roll
@@ -191,6 +195,7 @@ public:
{
const snd_seq_event_t& seqEvent(events[i]);

// FIXME
if (seqEvent.data.note.channel > 0xF || seqEvent.data.control.channel > 0xF)
continue;

@@ -264,8 +269,7 @@ public:

#if defined(DISTRHO_PLUGIN_TARGET_DSSI) && ! DISTRHO_PLUGIN_IS_SYNTH
return; // unused
(void)events;
(void)eventCount;
(void)events; (void)eventCount;
#endif
}

@@ -286,7 +290,7 @@ public:
# endif

# if DISTRHO_PLUGIN_WANT_PROGRAMS
const DSSI_Program_Descriptor* dssi_get_program(const unsigned long index)
const DSSI_Program_Descriptor* dssi_get_program(const ulong index)
{
if (index >= fPlugin.getProgramCount())
return nullptr;
@@ -300,12 +304,11 @@ public:
return &desc;
}

void dssi_select_program(const unsigned long bank, const unsigned long program)
void dssi_select_program(const ulong bank, const ulong program)
{
const unsigned long realProgram(bank * 128 + program);
const ulong realProgram(bank * 128 + program);

if (realProgram >= fPlugin.getProgramCount())
return;
DISTRHO_SAFE_ASSERT_RETURN(realProgram < fPlugin.getProgramCount(),);

fPlugin.setProgram(realProgram);

@@ -372,7 +375,7 @@ private:

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

static LADSPA_Handle ladspa_instantiate(const LADSPA_Descriptor*, unsigned long sampleRate)
static LADSPA_Handle ladspa_instantiate(const LADSPA_Descriptor*, ulong sampleRate)
{
if (d_lastBufferSize == 0)
d_lastBufferSize = 2048;
@@ -383,7 +386,7 @@ static LADSPA_Handle ladspa_instantiate(const LADSPA_Descriptor*, unsigned long

#define instancePtr ((PluginLadspaDssi*)instance)

static void ladspa_connect_port(LADSPA_Handle instance, unsigned long port, LADSPA_Data* dataLocation)
static void ladspa_connect_port(LADSPA_Handle instance, ulong port, LADSPA_Data* dataLocation)
{
instancePtr->ladspa_connect_port(port, dataLocation);
}
@@ -393,7 +396,7 @@ static void ladspa_activate(LADSPA_Handle instance)
instancePtr->ladspa_activate();
}

static void ladspa_run(LADSPA_Handle instance, unsigned long sampleCount)
static void ladspa_run(LADSPA_Handle instance, ulong sampleCount)
{
instancePtr->ladspa_run(sampleCount);
}
@@ -417,19 +420,19 @@ static char* dssi_configure(LADSPA_Handle instance, const char* key, const char*
# endif

# if DISTRHO_PLUGIN_WANT_PROGRAMS
static const DSSI_Program_Descriptor* dssi_get_program(LADSPA_Handle instance, unsigned long index)
static const DSSI_Program_Descriptor* dssi_get_program(LADSPA_Handle instance, ulong index)
{
return instancePtr->dssi_get_program(index);
}

static void dssi_select_program(LADSPA_Handle instance, unsigned long bank, unsigned long program)
static void dssi_select_program(LADSPA_Handle instance, ulong bank, ulong program)
{
instancePtr->dssi_select_program(bank, program);
}
# endif

# if DISTRHO_PLUGIN_IS_SYNTH
static void dssi_run_synth(LADSPA_Handle instance, unsigned long sampleCount, snd_seq_event_t* events, unsigned long eventCount)
static void dssi_run_synth(LADSPA_Handle instance, ulong sampleCount, snd_seq_event_t* events, ulong eventCount)
{
instancePtr->dssi_run_synth(sampleCount, events, eventCount);
}
@@ -443,7 +446,7 @@ static void dssi_run_synth(LADSPA_Handle instance, unsigned long sampleCount, sn
static LADSPA_Descriptor sLadspaDescriptor = {
/* UniqueID */ 0,
/* Label */ nullptr,
/* Properties */ LADSPA_PROPERTY_REALTIME | LADSPA_PROPERTY_HARD_RT_CAPABLE,
/* Properties */ LADSPA_PROPERTY_HARD_RT_CAPABLE,
/* Name */ nullptr,
/* Maker */ nullptr,
/* Copyright */ nullptr,
@@ -506,8 +509,8 @@ public:
d_lastSampleRate = 0.0;

// Get port count, init
unsigned long port = 0;
unsigned long portCount = DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS + plugin.getParameterCount();
ulong port = 0;
ulong portCount = DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS + plugin.getParameterCount();
#if DISTRHO_PLUGIN_WANT_LATENCY
portCount += 1;
#endif
@@ -517,7 +520,7 @@ public:

// Set ports
#if DISTRHO_PLUGIN_NUM_INPUTS > 0
for (unsigned long i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i, ++port)
for (ulong i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i, ++port)
{
char portName[24] = { '\0' };
std::sprintf(portName, "Audio Input %lu", i+1);
@@ -532,7 +535,7 @@ public:
#endif

#if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
for (unsigned long i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i, ++port)
for (ulong i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i, ++port)
{
char portName[24] = { '\0' };
std::sprintf(portName, "Audio Output %lu", i+1);
@@ -556,7 +559,7 @@ public:
++port;
#endif

for (unsigned long i=0, count=plugin.getParameterCount(); i < count; ++i, ++port)
for (ulong i=0, count=plugin.getParameterCount(); i < count; ++i, ++port)
{
portNames[port] = strdup((const char*)plugin.getParameterName(i));
portDescriptors[port] = LADSPA_PORT_CONTROL;
@@ -665,7 +668,7 @@ public:

if (sLadspaDescriptor.PortNames != nullptr)
{
for (unsigned long i=0; i < sLadspaDescriptor.PortCount; ++i)
for (ulong i=0; i < sLadspaDescriptor.PortCount; ++i)
{
if (sLadspaDescriptor.PortNames[i] != nullptr)
std::free((void*)sLadspaDescriptor.PortNames[i]);
@@ -684,7 +687,7 @@ static DescriptorInitializer sDescInit;
END_NAMESPACE_DISTRHO

DISTRHO_PLUGIN_EXPORT
const LADSPA_Descriptor* ladspa_descriptor(unsigned long index)
const LADSPA_Descriptor* ladspa_descriptor(ulong index)
{
USE_NAMESPACE_DISTRHO
return (index == 0) ? &sLadspaDescriptor : nullptr;
@@ -692,7 +695,7 @@ const LADSPA_Descriptor* ladspa_descriptor(unsigned long index)

#ifdef DISTRHO_PLUGIN_TARGET_DSSI
DISTRHO_PLUGIN_EXPORT
const DSSI_Descriptor* dssi_descriptor(unsigned long index)
const DSSI_Descriptor* dssi_descriptor(ulong index)
{
USE_NAMESPACE_DISTRHO
return (index == 0) ? &sDssiDescriptor : nullptr;


+ 112
- 4
source/modules/distrho/src/DistrhoPluginLV2.cpp View File

@@ -34,6 +34,7 @@
#endif

#include <map>
#include <string>

#ifndef DISTRHO_PLUGIN_URI
# error DISTRHO_PLUGIN_URI undefined!
@@ -110,6 +111,20 @@ public:
#if DISTRHO_PLUGIN_WANT_LATENCY
fPortLatency = nullptr;
#endif

#if DISTRHO_PLUGIN_WANT_STATE
if (const uint32_t count = fPlugin.getStateCount())
{
fNeededUiSends = new bool[count];

for (uint32_t i=0; i < count; ++i)
fNeededUiSends[i] = false;
}
else
{
fNeededUiSends = nullptr;
}
#endif
}

~PluginLv2()
@@ -127,6 +142,12 @@ public:
}

#if DISTRHO_PLUGIN_WANT_STATE
if (fNeededUiSends != nullptr)
{
delete[] fNeededUiSends;
fNeededUiSends = nullptr;
}

fStateMap.clear();
#endif
}
@@ -384,7 +405,18 @@ public:
if (event->body.type == fURIDs.distrhoState && fWorker != nullptr)
{
const void* const data((const void*)(event + 1));
fWorker->schedule_work(fWorker->handle, event->body.size, data);

// check if this is our special message
if (std::strcmp((const char*)data, "__dpf_ui_data__") == 0)
{
for (uint32_t i=0, count=fPlugin.getStateCount(); i < count; ++i)
fNeededUiSends[i] = true;
}
else
// no, send to DSP as usual
{
fWorker->schedule_work(fWorker->handle, event->body.size, data);
}

continue;
}
@@ -404,10 +436,76 @@ public:
fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount);
#endif

updateParameterOutputs();

#if DISTRHO_LV2_USE_EVENTS_OUT
#endif
const uint32_t capacity = fPortEventsOut->atom.size;

updateParameterOutputs();
bool needsInit = true;
uint32_t size, offset = 0;
LV2_Atom_Event* aev;

for (uint32_t i=0, count=fPlugin.getStateCount(); i < count; ++i)
{
if (! fNeededUiSends[i])
continue;

const d_string& key = fPlugin.getStateKey(i);

for (auto it = fStateMap.begin(), end = fStateMap.end(); it != end; ++it)
{
const d_string& curKey = it->first;

if (curKey != key)
continue;

const d_string& value = it->second;

// TODO - RT safe
d_stdout("Got msg (from DSP to UI via host):\n%s\n%s", (const char*)key, (const char*)value);

// join key and value
std::string tmpStr;
tmpStr += std::string(key);
tmpStr += std::string("\0", 1);
tmpStr += std::string(value);

// get msg size
const size_t msgSize(tmpStr.size()+1);

if (sizeof(LV2_Atom_Event) + msgSize > capacity - offset)
return;

if (needsInit)
{
fPortEventsOut->atom.size = 0;
fPortEventsOut->atom.type = fURIDs.atomSequence;
fPortEventsOut->body.unit = 0;
fPortEventsOut->body.pad = 0;
needsInit = false;
}

// reserve atom space
const size_t atomSize(lv2_atom_pad_size(sizeof(LV2_Atom) + msgSize));
char atomBuf[atomSize];
std::memset(atomBuf, 0, atomSize);

// put data
aev = (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, fPortEventsOut) + offset);
aev->time.frames = 0;
aev->body.type = fURIDs.distrhoState;
aev->body.size = msgSize;
std::memcpy(LV2_ATOM_BODY(&aev->body), tmpStr.data(), msgSize-1);

size = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + msgSize);
offset += size;
fPortEventsOut->atom.size += size;

fNeededUiSends[i] = false;
break;
}
}
#endif
}

// -------------------------------------------------------------------
@@ -538,6 +636,13 @@ public:
continue;

setState(key, value);

d_stdout("Got state msg:\n%s\n%s", (const char*)key, value);

#if DISTRHO_LV2_USE_EVENTS_OUT
// signal msg needed for UI
fNeededUiSends[i] = true;
#endif
}

return LV2_STATE_SUCCESS;
@@ -610,6 +715,7 @@ private:
LV2_URID atomFloat;
LV2_URID atomInt;
LV2_URID atomLong;
LV2_URID atomSequence;
LV2_URID atomString;
LV2_URID distrhoState;
LV2_URID midiEvent;
@@ -629,6 +735,7 @@ private:
atomFloat(uridMap->map(uridMap->handle, LV2_ATOM__Float)),
atomInt(uridMap->map(uridMap->handle, LV2_ATOM__Int)),
atomLong(uridMap->map(uridMap->handle, LV2_ATOM__Long)),
atomSequence(uridMap->map(uridMap->handle, LV2_ATOM__Sequence)),
atomString(uridMap->map(uridMap->handle, LV2_ATOM__String)),
distrhoState(uridMap->map(uridMap->handle, "urn:distrho:keyValueState")),
midiEvent(uridMap->map(uridMap->handle, LV2_MIDI__MidiEvent)),
@@ -650,13 +757,14 @@ private:

#if DISTRHO_PLUGIN_WANT_STATE
StringMap fStateMap;
bool* fNeededUiSends;

void setState(const char* const key, const char* const newValue)
{
fPlugin.setState(key, newValue);

// check if we want to save this key
if (! fPlugin.wantsStateKey(key))
if (! fPlugin.wantStateKey(key))
return;

// check if key already exists


+ 8
- 0
source/modules/distrho/src/DistrhoPluginLV2export.cpp View File

@@ -22,6 +22,7 @@
#include "lv2/instance-access.h"
#include "lv2/midi.h"
#include "lv2/options.h"
#include "lv2/resize-port.h"
#include "lv2/state.h"
#include "lv2/time.h"
#include "lv2/ui.h"
@@ -37,6 +38,10 @@
# error DISTRHO_PLUGIN_URI undefined!
#endif

#ifndef DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE
# define DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE 2048
#endif

#define DISTRHO_LV2_USE_EVENTS_IN (DISTRHO_PLUGIN_IS_SYNTH || DISTRHO_PLUGIN_WANT_TIMEPOS || (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI))
#define DISTRHO_LV2_USE_EVENTS_OUT (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)

@@ -130,6 +135,7 @@ void lv2_generate_ttl(const char* const basename)
pluginString += "@prefix doap: <http://usefulinc.com/ns/doap#> .\n";
pluginString += "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n";
pluginString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n";
pluginString += "@prefix rsz: <" LV2_RESIZE_PORT_PREFIX "> .\n";
#if DISTRHO_PLUGIN_HAS_UI
pluginString += "@prefix ui: <" LV2_UI_PREFIX "> .\n";
#endif
@@ -226,6 +232,7 @@ void lv2_generate_ttl(const char* const basename)
pluginString += " lv2:index " + d_string(portIndex) + " ;\n";
pluginString += " lv2:name \"Events Input\" ;\n";
pluginString += " lv2:symbol \"lv2_events_in\" ;\n";
pluginString += " rsz:minimumSize " + d_string(DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE) + " ;\n";
pluginString += " atom:bufferType atom:Sequence ;\n";
# if (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)
pluginString += " atom:supports <" LV2_ATOM__String "> ;\n";
@@ -247,6 +254,7 @@ void lv2_generate_ttl(const char* const basename)
pluginString += " lv2:index " + d_string(portIndex) + " ;\n";
pluginString += " lv2:name \"Events Output\" ;\n";
pluginString += " lv2:symbol \"lv2_events_out\" ;\n";
pluginString += " rsz:minimumSize " + d_string(DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE) + " ;\n";
pluginString += " atom:bufferType atom:Sequence ;\n";
pluginString += " atom:supports <" LV2_ATOM__String "> ;\n";
pluginString += " ] ;\n\n";


+ 3
- 3
source/modules/distrho/src/DistrhoPluginVST.cpp View File

@@ -215,7 +215,7 @@ protected:
#endif
}

void uiResize(const unsigned int width, const unsigned int height)
void uiResize(const uint width, const uint height)
{
fUI.setSize(width, height);
hostCallback(audioMasterSizeWindow, width, height, nullptr, 0.0f);
@@ -256,7 +256,7 @@ private:
handlePtr->sendNote(channel, note, velocity);
}

static void uiResizeCallback(void* ptr, unsigned int width, unsigned int height)
static void uiResizeCallback(void* ptr, uint width, uint height)
{
handlePtr->uiResize(width, height);
}
@@ -753,7 +753,7 @@ private:
fPlugin.setState(newKey, newValue);

// check if we want to save this key
if (! fPlugin.wantsStateKey(newKey))
if (! fPlugin.wantStateKey(newKey))
return;

// check if key already exists


+ 4
- 4
source/modules/distrho/src/DistrhoUI.cpp View File

@@ -23,7 +23,7 @@ END_NAMESPACE_DGL
START_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------
// Static data
// Static data, see DistrhoUIInternal.hpp

double d_lastUiSampleRate = 0.0;

@@ -34,7 +34,7 @@ UI::UI()
: DGL::Widget(*DGL::dgl_lastUiParent),
pData(new PrivateData())
{
assert(DGL::dgl_lastUiParent != nullptr);
DISTRHO_SAFE_ASSERT(DGL::dgl_lastUiParent != nullptr);

DGL::dgl_lastUiParent = nullptr;
}
@@ -79,7 +79,7 @@ void UI::d_sendNote(uint8_t channel, uint8_t note, uint8_t velocity)
// -----------------------------------------------------------------------
// Host UI State

void UI::d_uiResize(unsigned int width, unsigned int height)
void UI::d_uiResize(uint width, uint height)
{
pData->uiResizeCallback(width, height);
}
@@ -88,7 +88,7 @@ void UI::d_uiResize(unsigned int width, unsigned int height)
// -----------------------------------------------------------------------
// Direct DSP access

void* UI::d_getPluginInstancePointer()
void* UI::d_getPluginInstancePointer() const noexcept
{
return pData->dspPtr;
}


+ 5
- 5
source/modules/distrho/src/DistrhoUIDSSI.cpp View File

@@ -60,7 +60,7 @@ struct OscData {
lo_send(addr, targetPath, "if", index, value);
}

void send_midi(unsigned char data[4]) const
void send_midi(uchar data[4]) const
{
char targetPath[std::strlen(path)+6];
std::strcpy(targetPath, path);
@@ -126,13 +126,13 @@ public:
}
#endif

void dssiui_control(unsigned long index, float value)
void dssiui_control(ulong index, float value)
{
fUI.parameterChanged(index, value);
}

#if DISTRHO_PLUGIN_WANT_PROGRAMS
void dssiui_program(unsigned long bank, unsigned long program)
void dssiui_program(ulong bank, ulong program)
{
fUI.programChanged(bank * 128 + program);
}
@@ -186,7 +186,7 @@ protected:
fOscData.send_midi(mdata);
}

void uiResize(const unsigned int width, const unsigned int height)
void uiResize(const uint width, const uint height)
{
fUI.setSize(width, height);
}
@@ -217,7 +217,7 @@ private:
uiPtr->sendNote(channel, note, velocity);
}

static void uiResizeCallback(void* ptr, unsigned int width, unsigned int height)
static void uiResizeCallback(void* ptr, uint width, uint height)
{
uiPtr->uiResize(width, height);
}


+ 40
- 24
source/modules/distrho/src/DistrhoUIInternal.hpp View File

@@ -36,7 +36,7 @@ typedef void (*editParamFunc) (void* ptr, uint32_t rindex, bool started);
typedef void (*setParamFunc) (void* ptr, uint32_t rindex, float value);
typedef void (*setStateFunc) (void* ptr, const char* key, const char* value);
typedef void (*sendNoteFunc) (void* ptr, uint8_t channel, uint8_t note, uint8_t velo);
typedef void (*uiResizeFunc) (void* ptr, unsigned int width, unsigned int height);
typedef void (*uiResizeFunc) (void* ptr, uint width, uint height);

// -----------------------------------------------------------------------
// UI private data
@@ -70,7 +70,7 @@ struct UI::PrivateData {
uiResizeCallbackFunc(nullptr),
ptr(nullptr)
{
assert(sampleRate != 0.0);
DISTRHO_SAFE_ASSERT(sampleRate != 0.0);

#if defined(DISTRHO_PLUGIN_TARGET_DSSI) || defined(DISTRHO_PLUGIN_TARGET_LV2)
parameterOffset += DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS;
@@ -78,6 +78,7 @@ struct UI::PrivateData {
parameterOffset += 1;
# endif
#endif

#ifdef DISTRHO_PLUGIN_TARGET_LV2
# if (DISTRHO_PLUGIN_IS_SYNTH || DISTRHO_PLUGIN_WANT_TIMEPOS || DISTRHO_PLUGIN_WANT_STATE)
parameterOffset += 1;
@@ -112,7 +113,7 @@ struct UI::PrivateData {
sendNoteCallbackFunc(ptr, channel, note, velocity);
}

void uiResizeCallback(const unsigned int width, const unsigned int height)
void uiResizeCallback(const uint width, const uint height)
{
if (uiResizeCallbackFunc != nullptr)
uiResizeCallbackFunc(ptr, width, height);
@@ -126,16 +127,15 @@ class UIExporter
{
public:
UIExporter(void* const ptr, const intptr_t winId,
const editParamFunc editParamCall, const setParamFunc setParamCall, const setStateFunc setStateCall, const sendNoteFunc sendNoteCall, const uiResizeFunc uiResizeCall, void* const dspPtr = nullptr)
const editParamFunc editParamCall, const setParamFunc setParamCall, const setStateFunc setStateCall, const sendNoteFunc sendNoteCall, const uiResizeFunc uiResizeCall,
void* const dspPtr = nullptr)
: glApp(),
glWindow(glApp, winId),
fUi(createUI()),
fData((fUi != nullptr) ? fUi->pData : nullptr)
{
assert(fUi != nullptr);

if (fUi == nullptr)
return;
DISTRHO_SAFE_ASSERT_RETURN(fUi != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);

fData->ptr = ptr;
fData->editParamCallbackFunc = editParamCall;
@@ -164,47 +164,60 @@ public:

const char* getName() const noexcept
{
return (fUi != nullptr) ? fUi->d_getName() : "";
DISTRHO_SAFE_ASSERT_RETURN(fUi != nullptr, "");

return fUi->d_getName();
}

unsigned int getWidth() const noexcept
uint getWidth() const noexcept
{
return (fUi != nullptr) ? fUi->d_getWidth() : 0;
DISTRHO_SAFE_ASSERT_RETURN(fUi != nullptr, 0);

return fUi->d_getWidth();
}

unsigned int getHeight() const noexcept
uint getHeight() const noexcept
{
return (fUi != nullptr) ? fUi->d_getHeight() : 0;
DISTRHO_SAFE_ASSERT_RETURN(fUi != nullptr, 0);

return fUi->d_getHeight();
}

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

uint32_t getParameterOffset() const noexcept
{
return (fData != nullptr) ? fData->parameterOffset : 0;
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);

return fData->parameterOffset;
}

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

void parameterChanged(const uint32_t index, const float value)
{
if (fUi != nullptr)
fUi->d_parameterChanged(index, value);
DISTRHO_SAFE_ASSERT_RETURN(fUi != nullptr,);

fUi->d_parameterChanged(index, value);
}

#if DISTRHO_PLUGIN_WANT_PROGRAMS
void programChanged(const uint32_t index)
{
if (fUi != nullptr)
fUi->d_programChanged(index);
DISTRHO_SAFE_ASSERT_RETURN(fUi != nullptr,);

fUi->d_programChanged(index);
}
#endif

#if DISTRHO_PLUGIN_WANT_STATE
void stateChanged(const char* const key, const char* const value)
{
if (fUi != nullptr)
fUi->d_stateChanged(key, value);
DISTRHO_SAFE_ASSERT_RETURN(fUi != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
DISTRHO_SAFE_ASSERT_RETURN(value != nullptr,);

fUi->d_stateChanged(key, value);
}
#endif

@@ -212,9 +225,9 @@ public:

bool idle()
{
if (fUi != nullptr)
fUi->d_uiIdle();
DISTRHO_SAFE_ASSERT_RETURN(fUi != nullptr, false);

fUi->d_uiIdle();
glApp.idle();

return ! glApp.isQuiting();
@@ -226,7 +239,7 @@ public:
glApp.quit();
}

void setSize(const unsigned int width, const unsigned int height)
void setSize(const uint width, const uint height)
{
glWindow.setSize(width, height);
}
@@ -254,10 +267,13 @@ private:
DGL::Window glWindow;

// -------------------------------------------------------------------
// private members accessed by DistrhoPlugin class
// private members accessed by DistrhoUI classes

UI* const fUi;
UI::PrivateData* const fData;

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UIExporter)
DISTRHO_PREVENT_HEAP_ALLOCATION
};

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


+ 25
- 7
source/modules/distrho/src/DistrhoUILV2.cpp View File

@@ -40,9 +40,16 @@ public:
fUiResize(uiResz),
fUiTouch(uiTouch),
fController(controller),
fWriteFunction(writeFunc)
fWriteFunction(writeFunc),
fEventTransferURID(uridMap->map(uridMap->handle, LV2_ATOM__eventTransfer)),
fKeyValueURID(uridMap->map(uridMap->handle, "urn:distrho:keyValueState"))
{
fUiResize->ui_resize(fUiResize->handle, fUI.getWidth(), fUI.getHeight());

#if DISTRHO_PLUGIN_WANT_STATE
// tell the DSP we're ready to receive msgs
setState("__dpf_ui_data__", "");
#endif
}

// -------------------------------------------------------------------
@@ -61,10 +68,17 @@ public:
const float value(*(const float*)buffer);
fUI.parameterChanged(rindex-parameterOffset, value);
}
else
#if DISTRHO_PLUGIN_WANT_STATE
else if (format == fEventTransferURID)
{
//fUI.stateChanged(key, value);
const LV2_Atom* const atom((const LV2_Atom*)buffer);
const char* const stateKey((const char*)LV2_ATOM_BODY_CONST(atom));
const char* const stateValue(stateKey+std::strlen(stateKey)+1);

d_stdout("Got MSG in UI from DSP ==> %s | %s", stateKey, stateValue);
fUI.stateChanged(stateKey, stateValue);
}
#endif
}

// -------------------------------------------------------------------
@@ -125,20 +139,20 @@ protected:
// set atom info
LV2_Atom* const atom((LV2_Atom*)atomBuf);
atom->size = msgSize;
atom->type = fUridMap->map(fUridMap->handle, "urn:distrho:keyValueState");
atom->type = fKeyValueURID;

// set atom data
std::memcpy(atomBuf + sizeof(LV2_Atom), tmpStr.data(), msgSize-1);

// send to DSP side
fWriteFunction(fController, eventInPortIndex, atomSize, fUridMap->map(fUridMap->handle, LV2_ATOM__eventTransfer), atom);
fWriteFunction(fController, eventInPortIndex, atomSize, fEventTransferURID, atom);
}

void sendNote(const uint8_t /*channel*/, const uint8_t /*note*/, const uint8_t /*velocity*/)
{
}

void uiResize(const unsigned int width, const unsigned int height)
void uiResize(const uint width, const uint height)
{
fUI.setSize(width, height);
fUiResize->ui_resize(fUiResize->handle, width, height);
@@ -156,6 +170,10 @@ private:
const LV2UI_Controller fController;
const LV2UI_Write_Function fWriteFunction;

// Need to save this
const LV2_URID fEventTransferURID;
const LV2_URID fKeyValueURID;

// -------------------------------------------------------------------
// Callbacks

@@ -181,7 +199,7 @@ private:
uiPtr->sendNote(channel, note, velocity);
}

static void uiResizeCallback(void* ptr, unsigned int width, unsigned int height)
static void uiResizeCallback(void* ptr, uint width, uint height)
{
uiPtr->uiResize(width, height);
}


+ 154
- 26
source/modules/distrho/src/lv2/atom-forge.h View File

@@ -1,5 +1,5 @@
/*
Copyright 2008-2012 David Robillard <http://drobilla.net>
Copyright 2008-2013 David Robillard <http://drobilla.net>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -48,6 +48,12 @@
#include "atom-util.h"
#include "urid.h"

#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
# define LV2_ATOM_FORGE_DEPRECATED __attribute__((__deprecated__))
#else
# define LV2_ATOM_FORGE_DEPRECATED
#endif

#ifdef __cplusplus
extern "C" {
#else
@@ -89,7 +95,7 @@ typedef struct {

LV2_Atom_Forge_Frame* stack;

LV2_URID Blank;
LV2_URID Blank LV2_ATOM_FORGE_DEPRECATED;
LV2_URID Bool;
LV2_URID Chunk;
LV2_URID Double;
@@ -97,9 +103,10 @@ typedef struct {
LV2_URID Int;
LV2_URID Long;
LV2_URID Literal;
LV2_URID Object;
LV2_URID Path;
LV2_URID Property;
LV2_URID Resource;
LV2_URID Resource LV2_ATOM_FORGE_DEPRECATED;
LV2_URID Sequence;
LV2_URID String;
LV2_URID Tuple;
@@ -120,6 +127,13 @@ lv2_atom_forge_set_buffer(LV2_Atom_Forge* forge, uint8_t* buf, size_t size);
static inline void
lv2_atom_forge_init(LV2_Atom_Forge* forge, LV2_URID_Map* map)
{
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
lv2_atom_forge_set_buffer(forge, NULL, 0);
forge->Blank = map->map(map->handle, LV2_ATOM__Blank);
forge->Bool = map->map(map->handle, LV2_ATOM__Bool);
@@ -129,6 +143,7 @@ lv2_atom_forge_init(LV2_Atom_Forge* forge, LV2_URID_Map* map)
forge->Int = map->map(map->handle, LV2_ATOM__Int);
forge->Long = map->map(map->handle, LV2_ATOM__Long);
forge->Literal = map->map(map->handle, LV2_ATOM__Literal);
forge->Object = map->map(map->handle, LV2_ATOM__Object);
forge->Path = map->map(map->handle, LV2_ATOM__Path);
forge->Property = map->map(map->handle, LV2_ATOM__Property);
forge->Resource = map->map(map->handle, LV2_ATOM__Resource);
@@ -138,6 +153,11 @@ lv2_atom_forge_init(LV2_Atom_Forge* forge, LV2_URID_Map* map)
forge->URI = map->map(map->handle, LV2_ATOM__URI);
forge->URID = map->map(map->handle, LV2_ATOM__URID);
forge->Vector = map->map(map->handle, LV2_ATOM__Vector);
#if defined(__clang__)
# pragma clang diagnostic pop
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
# pragma GCC diagnostic pop
#endif
}

static inline LV2_Atom*
@@ -184,8 +204,51 @@ lv2_atom_forge_pop(LV2_Atom_Forge* forge, LV2_Atom_Forge_Frame* frame)
static inline bool
lv2_atom_forge_top_is(LV2_Atom_Forge* forge, uint32_t type)
{
return forge->stack &&
lv2_atom_forge_deref(forge, forge->stack->ref)->type == type;
return forge->stack && forge->stack->ref &&
(lv2_atom_forge_deref(forge, forge->stack->ref)->type == type);
}

/** Return true iff @p type is an atom:Object. */
static inline bool
lv2_atom_forge_is_object_type(const LV2_Atom_Forge* forge, uint32_t type)
{
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
return (type == forge->Object ||
type == forge->Blank ||
type == forge->Resource);
#if defined(__clang__)
# pragma clang diagnostic pop
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
# pragma GCC diagnostic pop
#endif
}

/** Return true iff @p type is an atom:Object with a blank ID. */
static inline bool
lv2_atom_forge_is_blank(const LV2_Atom_Forge* forge,
uint32_t type,
const LV2_Atom_Object_Body* body)
{
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
return (type == forge->Blank ||
(type == forge->Object && body->id == 0));
#if defined(__clang__)
# pragma clang diagnostic pop
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
# pragma GCC diagnostic pop
#endif
}

/**
@@ -199,7 +262,7 @@ static inline void
lv2_atom_forge_set_buffer(LV2_Atom_Forge* forge, uint8_t* buf, size_t size)
{
forge->buf = buf;
forge->size = size;
forge->size = (uint32_t)size;
forge->offset = 0;
forge->deref = NULL;
forge->sink = NULL;
@@ -253,7 +316,7 @@ lv2_atom_forge_raw(LV2_Atom_Forge* forge, const void* data, uint32_t size)
if (forge->sink) {
out = forge->sink(forge->handle, data, size);
} else {
out = (LV2_Atom_Forge_Ref)forge->buf + forge->offset;
out = (LV2_Atom_Forge_Ref)forge->buf + (LV2_Atom_Forge_Ref)forge->offset;
uint8_t* mem = forge->buf + forge->offset;
if (forge->offset + size > forge->size) {
return 0;
@@ -321,7 +384,8 @@ lv2_atom_forge_primitive(LV2_Atom_Forge* forge, const LV2_Atom* a)
if (lv2_atom_forge_top_is(forge, forge->Vector)) {
return lv2_atom_forge_raw(forge, LV2_ATOM_BODY_CONST(a), a->size);
} else {
return lv2_atom_forge_write(forge, a, sizeof(LV2_Atom) + a->size);
return lv2_atom_forge_write(
forge, a, (uint32_t)sizeof(LV2_Atom) + a->size);
}
}

@@ -503,7 +567,7 @@ lv2_atom_forge_tuple(LV2_Atom_Forge* forge, LV2_Atom_Forge_Frame* frame)
}

/**
Write the header of an atom:Resource.
Write the header of an atom:Object.

The passed frame will be initialised to represent this object. To complete
the object, write a sequence of properties, then pop the frame with
@@ -514,12 +578,12 @@ lv2_atom_forge_tuple(LV2_Atom_Forge* forge, LV2_Atom_Forge_Frame* frame)
LV2_URID eg_Cat = map("http://example.org/Cat");
LV2_URID eg_name = map("http://example.org/name");

// Write object header
// Start object with type eg_Cat and blank ID
LV2_Atom_Forge_Frame frame;
lv2_atom_forge_resource(forge, &frame, 1, eg_Cat);
lv2_atom_forge_object(forge, &frame, 0, eg_Cat);

// Write property: eg:name = "Hobbes"
lv2_atom_forge_property_head(forge, eg_name, 0);
// Append property eg:name = "Hobbes"
lv2_atom_forge_key(forge, eg_name);
lv2_atom_forge_string(forge, "Hobbes", strlen("Hobbes"));

// Finish object
@@ -527,39 +591,103 @@ lv2_atom_forge_tuple(LV2_Atom_Forge* forge, LV2_Atom_Forge_Frame* frame)
@endcode
*/
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_object(LV2_Atom_Forge* forge,
LV2_Atom_Forge_Frame* frame,
LV2_URID id,
LV2_URID otype)
{
const LV2_Atom_Object a = {
{ (uint32_t)sizeof(LV2_Atom_Object_Body), forge->Object },
{ id, otype }
};
return lv2_atom_forge_push(
forge, frame, lv2_atom_forge_write(forge, &a, sizeof(a)));
}

/**
The same as lv2_atom_forge_object(), but for object:Resource.

This function is deprecated and should not be used in new code.
Use lv2_atom_forge_object() directly instead.
*/
LV2_ATOM_FORGE_DEPRECATED
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_resource(LV2_Atom_Forge* forge,
LV2_Atom_Forge_Frame* frame,
LV2_URID id,
LV2_URID otype)
{
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
const LV2_Atom_Object a = {
{ sizeof(LV2_Atom_Object) - sizeof(LV2_Atom), forge->Resource },
{ (uint32_t)sizeof(LV2_Atom_Object_Body), forge->Resource },
{ id, otype }
};
LV2_Atom_Forge_Ref out = lv2_atom_forge_write(forge, &a, sizeof(a));
return lv2_atom_forge_push(forge, frame, out);
return lv2_atom_forge_push(
forge, frame, lv2_atom_forge_write(forge, &a, sizeof(a)));
#if defined(__clang__)
# pragma clang diagnostic pop
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
# pragma GCC diagnostic pop
#endif
}

/**
The same as lv2_atom_forge_resource(), but for object:Blank.
The same as lv2_atom_forge_object(), but for object:Blank.

This function is deprecated and should not be used in new code.
Use lv2_atom_forge_object() directly instead.
*/
LV2_ATOM_FORGE_DEPRECATED
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_blank(LV2_Atom_Forge* forge,
LV2_Atom_Forge_Frame* frame,
uint32_t id,
LV2_URID otype)
{
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
const LV2_Atom_Object a = {
{ sizeof(LV2_Atom_Object) - sizeof(LV2_Atom), forge->Blank },
{ (uint32_t)sizeof(LV2_Atom_Object_Body), forge->Blank },
{ id, otype }
};
LV2_Atom_Forge_Ref out = lv2_atom_forge_write(forge, &a, sizeof(a));
return lv2_atom_forge_push(forge, frame, out);
return lv2_atom_forge_push(
forge, frame, lv2_atom_forge_write(forge, &a, sizeof(a)));
#if defined(__clang__)
# pragma clang diagnostic pop
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
# pragma GCC diagnostic pop
#endif
}

/**
Write a property key in an Object, to be followed by the value.

See lv2_atom_forge_object() documentation for an example.
*/
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_key(LV2_Atom_Forge* forge,
LV2_URID key)
{
const LV2_Atom_Property_Body a = { key, 0, { 0, 0 } };
return lv2_atom_forge_write(forge, &a, 2 * (uint32_t)sizeof(uint32_t));
}

/**
Write the header for a property body (likely in an Object).
See lv2_atom_forge_resource() documentation for an example.
Write the header for a property body in an object, with context.

If you do not need the context, which is almost certainly the case,
use the simpler lv2_atom_forge_key() instead.
*/
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_property_head(LV2_Atom_Forge* forge,
@@ -567,7 +695,7 @@ lv2_atom_forge_property_head(LV2_Atom_Forge* forge,
LV2_URID context)
{
const LV2_Atom_Property_Body a = { key, context, { 0, 0 } };
return lv2_atom_forge_write(forge, &a, 2 * sizeof(uint32_t));
return lv2_atom_forge_write(forge, &a, 2 * (uint32_t)sizeof(uint32_t));
}

/**
@@ -579,11 +707,11 @@ lv2_atom_forge_sequence_head(LV2_Atom_Forge* forge,
uint32_t unit)
{
const LV2_Atom_Sequence a = {
{ sizeof(LV2_Atom_Sequence) - sizeof(LV2_Atom), forge->Sequence },
{ (uint32_t)sizeof(LV2_Atom_Sequence_Body), forge->Sequence },
{ unit, 0 }
};
LV2_Atom_Forge_Ref out = lv2_atom_forge_write(forge, &a, sizeof(a));
return lv2_atom_forge_push(forge, frame, out);
return lv2_atom_forge_push(
forge, frame, lv2_atom_forge_write(forge, &a, sizeof(a)));
}

/**


+ 16
- 22
source/modules/distrho/src/lv2/atom-helpers.h View File

@@ -1,7 +1,7 @@
// lv2_atom_helpers.h
//
/****************************************************************************
Copyright (C) 2005-2012, rncbc aka Rui Nuno Capela. All rights reserved.
Copyright (C) 2005-2013, rncbc aka Rui Nuno Capela. All rights reserved.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -40,7 +40,7 @@
#include <stdlib.h>
#include <assert.h>

#include "atom.h"
#include "atom-util.h"

#ifdef __cplusplus
extern "C" {
@@ -59,28 +59,18 @@ struct _LV2_Atom_Buffer
} LV2_Atom_Buffer;


// Pad a size to 64 bits (for LV2 atom:Sequence event sizes).
//
static inline
uint32_t lv2_atom_buffer_pad_size ( uint32_t size )
{
return (size + 7) & (~7);
}


// Clear and initialize an existing LV2 atom:Sequenece buffer.
//
static inline
void lv2_atom_buffer_reset ( LV2_Atom_Buffer *buf, bool input )
{
if (input)
if (input) {
buf->atoms.atom.size = sizeof(LV2_Atom_Sequence_Body);
else
buf->atoms.atom.type = buf->sequence_type;
} else {
buf->atoms.atom.size = buf->capacity;

buf->atoms.atom.type = buf->sequence_type;
buf->atoms.body.unit = 0;
buf->atoms.body.pad = 0;
buf->atoms.atom.type = buf->chunk_type;
}
}


@@ -88,12 +78,13 @@ void lv2_atom_buffer_reset ( LV2_Atom_Buffer *buf, bool input )
//
static inline
LV2_Atom_Buffer *lv2_atom_buffer_new (
uint32_t capacity, uint32_t sequence_type, bool input )
uint32_t capacity, uint32_t chunk_type, uint32_t sequence_type, bool input )
{
LV2_Atom_Buffer *buf = (LV2_Atom_Buffer *)
malloc(sizeof(LV2_Atom_Buffer) + sizeof(LV2_Atom_Sequence) + capacity);

buf->capacity = capacity;
buf->chunk_type = chunk_type;
buf->sequence_type = sequence_type;

lv2_atom_buffer_reset(buf, input);
@@ -116,7 +107,10 @@ void lv2_atom_buffer_free ( LV2_Atom_Buffer *buf )
static inline
uint32_t lv2_atom_buffer_get_size ( LV2_Atom_Buffer *buf )
{
return buf->atoms.atom.size - sizeof(LV2_Atom_Sequence_Body);
if (buf->atoms.atom.type == buf->sequence_type)
return buf->atoms.atom.size - uint32_t(sizeof(LV2_Atom_Sequence_Body));
else
return 0;
}


@@ -160,7 +154,7 @@ bool lv2_atom_buffer_end (
LV2_Atom_Buffer_Iterator *iter, LV2_Atom_Buffer *buf )
{
iter->buf = buf;
iter->offset = lv2_atom_buffer_pad_size(lv2_atom_buffer_get_size(buf));
iter->offset = lv2_atom_pad_size(lv2_atom_buffer_get_size(buf));

return (iter->offset < buf->capacity - sizeof(LV2_Atom_Event));
}
@@ -187,7 +181,7 @@ bool lv2_atom_buffer_increment ( LV2_Atom_Buffer_Iterator *iter )
LV2_Atom_Sequence *atoms = &buf->atoms;
uint32_t size = ((LV2_Atom_Event *) ((char *)
LV2_ATOM_CONTENTS(LV2_Atom_Sequence, atoms) + iter->offset))->body.size;
iter->offset += lv2_atom_buffer_pad_size(sizeof(LV2_Atom_Event) + size);
iter->offset += lv2_atom_pad_size(uint32_t(sizeof(LV2_Atom_Event)) + size);

return true;
}
@@ -239,7 +233,7 @@ bool lv2_atom_buffer_write (

memcpy(LV2_ATOM_BODY(&ev->body), data, size);

size = lv2_atom_buffer_pad_size(sizeof(LV2_Atom_Event) + size);
size = lv2_atom_pad_size(uint32_t(sizeof(LV2_Atom_Event)) + size);
atoms->atom.size += size;
iter->offset += size;



+ 58
- 13
source/modules/distrho/src/lv2/atom-util.h View File

@@ -1,5 +1,5 @@
/*
Copyright 2008-2012 David Robillard <http://drobilla.net>
Copyright 2008-2013 David Robillard <http://drobilla.net>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -41,14 +41,14 @@ extern "C" {
static inline uint32_t
lv2_atom_pad_size(uint32_t size)
{
return (size + 7) & (~7);
return (size + 7U) & (~7U);
}

/** Return the total size of @p atom, including the header. */
static inline uint32_t
lv2_atom_total_size(const LV2_Atom* atom)
{
return sizeof(LV2_Atom) + atom->size;
return (uint32_t)sizeof(LV2_Atom) + atom->size;
}

/** Return true iff @p atom is null. */
@@ -80,10 +80,10 @@ lv2_atom_sequence_begin(const LV2_Atom_Sequence_Body* body)
}

/** Get an iterator pointing to the end of a Sequence body. */
static inline const LV2_Atom_Event*
lv2_atom_sequence_end(const LV2_Atom_Sequence_Body* body, uint32_t size)
static inline LV2_Atom_Event*
lv2_atom_sequence_end(LV2_Atom_Sequence_Body* body, uint32_t size)
{
return (const LV2_Atom_Event*)((const uint8_t*)body + lv2_atom_pad_size(size));
return (LV2_Atom_Event*)((uint8_t*)body + lv2_atom_pad_size(size));
}

/** Return true iff @p i has reached the end of @p body. */
@@ -99,7 +99,6 @@ lv2_atom_sequence_is_end(const LV2_Atom_Sequence_Body* body,
static inline const LV2_Atom_Event*
lv2_atom_sequence_next(const LV2_Atom_Event* i)
{
if (!i) return NULL;
return (const LV2_Atom_Event*)((const uint8_t*)i
+ sizeof(LV2_Atom_Event)
+ lv2_atom_pad_size(i->body.size));
@@ -128,6 +127,52 @@ lv2_atom_sequence_next(const LV2_Atom_Event* i)
!lv2_atom_sequence_is_end(body, size, (iter)); \
(iter) = lv2_atom_sequence_next(iter))

/**
@}
@name Sequence Utilities
@{
*/

/**
Clear all events from @p sequence.

This simply resets the size field, the other fields are left untouched.
*/
static inline void
lv2_atom_sequence_clear(LV2_Atom_Sequence* seq)
{
seq->atom.size = sizeof(LV2_Atom_Sequence_Body);
}

/**
Append an event at the end of @p sequence.

@param seq Sequence to append to.
@param capacity Total capacity of the sequence atom
(e.g. as set by the host for sequence output ports).
@param event Event to write.

@return A pointer to the newly written event in @p seq,
or NULL on failure (insufficient space).
*/
static inline LV2_Atom_Event*
lv2_atom_sequence_append_event(LV2_Atom_Sequence* seq,
uint32_t capacity,
const LV2_Atom_Event* event)
{
const uint32_t total_size = (uint32_t)sizeof(*event) + event->body.size;
if (capacity - seq->atom.size < total_size) {
return NULL;
}

LV2_Atom_Event* e = lv2_atom_sequence_end(&seq->body, seq->atom.size);
memcpy(e, event, total_size);

seq->atom.size += lv2_atom_pad_size(total_size);

return e;
}

/**
@}
@name Tuple Iterator
@@ -143,7 +188,7 @@ lv2_atom_tuple_begin(const LV2_Atom_Tuple* tup)

/** Return true iff @p i has reached the end of @p body. */
static inline bool
lv2_atom_tuple_is_end(const void* body, uint32_t size, LV2_Atom* i)
lv2_atom_tuple_is_end(const void* body, uint32_t size, const LV2_Atom* i)
{
return (const uint8_t*)i >= ((const uint8_t*)body + size);
}
@@ -169,13 +214,13 @@ lv2_atom_tuple_next(const LV2_Atom* i)
@endcode
*/
#define LV2_ATOM_TUPLE_FOREACH(tuple, iter) \
for (LV2_Atom* (iter) = lv2_atom_tuple_begin(tuple); \
!lv2_atom_tuple_is_end(LV2_ATOM_BODY(tuple), (tuple)->size, (iter)); \
for (const LV2_Atom* (iter) = lv2_atom_tuple_begin(tuple); \
!lv2_atom_tuple_is_end(LV2_ATOM_BODY_CONST(tuple), (tuple)->size, (iter)); \
(iter) = lv2_atom_tuple_next(iter))

/** Like LV2_ATOM_TUPLE_FOREACH but for a headerless tuple body. */
#define LV2_ATOM_TUPLE_BODY_FOREACH(body, size, iter) \
for (LV2_Atom* (iter) = (LV2_Atom*)body; \
for (const LV2_Atom* (iter) = (const LV2_Atom*)body; \
!lv2_atom_tuple_is_end(body, size, (iter)); \
(iter) = lv2_atom_tuple_next(iter))

@@ -208,8 +253,8 @@ lv2_atom_object_next(const LV2_Atom_Property_Body* i)
const LV2_Atom* const value = (const LV2_Atom*)(
(const uint8_t*)i + 2 * sizeof(uint32_t));
return (const LV2_Atom_Property_Body*)(
(const uint8_t*)i + lv2_atom_pad_size(sizeof(LV2_Atom_Property_Body)
+ value->size));
(const uint8_t*)i + lv2_atom_pad_size(
(uint32_t)sizeof(LV2_Atom_Property_Body) + value->size));
}

/**


+ 1
- 1
source/modules/distrho/src/lv2/atom.h View File

@@ -189,7 +189,7 @@ typedef struct {

/** The body of an atom:Object. May be cast to LV2_Atom. */
typedef struct {
uint32_t id; /**< URID (atom:Resource) or blank ID (atom:Blank). */
uint32_t id; /**< URID, or 0 for blank. */
uint32_t otype; /**< Type URID (same as rdf:type, for fast dispatch). */
/* Contents (a series of property bodies) follow here. */
} LV2_Atom_Object_Body;


+ 18
- 15
source/modules/distrho/src/lv2/event-helpers.h View File

@@ -50,7 +50,7 @@ extern "C" {
static inline uint16_t
lv2_event_pad_size(uint16_t size)
{
return (size + 7) & (~7);
return (uint16_t)(size + 7U) & (uint16_t)(~7U);
}


@@ -60,7 +60,7 @@ lv2_event_pad_size(uint16_t size)
static inline void
lv2_event_buffer_reset(LV2_Event_Buffer* buf,
uint16_t stamp_type,
uint8_t *data)
uint8_t* data)
{
buf->data = data;
buf->header_size = sizeof(LV2_Event_Buffer);
@@ -130,7 +130,8 @@ lv2_event_increment(LV2_Event_Iterator* iter)
LV2_Event* const ev = (LV2_Event*)(
(uint8_t*)iter->buf->data + iter->offset);

iter->offset += lv2_event_pad_size(sizeof(LV2_Event) + ev->size);
iter->offset += lv2_event_pad_size(
(uint16_t)((uint16_t)sizeof(LV2_Event) + ev->size));

return true;
}
@@ -190,7 +191,7 @@ lv2_event_write(LV2_Event_Iterator* iter,
memcpy((uint8_t*)ev + sizeof(LV2_Event), data, size);
++iter->buf->event_count;

size = lv2_event_pad_size(sizeof(LV2_Event) + size);
size = lv2_event_pad_size((uint16_t)(sizeof(LV2_Event) + size));
iter->buf->size += size;
iter->offset += size;

@@ -208,11 +209,12 @@ lv2_event_reserve(LV2_Event_Iterator* iter,
uint16_t type,
uint16_t size)
{
if (iter->buf->capacity - iter->buf->size < sizeof(LV2_Event) + size)
const uint16_t total_size = (uint16_t)(sizeof(LV2_Event) + size);
if (iter->buf->capacity - iter->buf->size < total_size)
return NULL;

LV2_Event* const ev = (LV2_Event*)((uint8_t*)iter->buf->data +
iter->offset);
LV2_Event* const ev = (LV2_Event*)(
(uint8_t*)iter->buf->data + iter->offset);

ev->frames = frames;
ev->subframes = subframes;
@@ -220,9 +222,9 @@ lv2_event_reserve(LV2_Event_Iterator* iter,
ev->size = size;
++iter->buf->event_count;

size = lv2_event_pad_size(sizeof(LV2_Event) + size);
iter->buf->size += size;
iter->offset += size;
const uint16_t padded_size = lv2_event_pad_size(total_size);
iter->buf->size += padded_size;
iter->offset += padded_size;

return (uint8_t*)ev + sizeof(LV2_Event);
}
@@ -238,19 +240,20 @@ lv2_event_write_event(LV2_Event_Iterator* iter,
const LV2_Event* ev,
const uint8_t* data)
{
if (iter->buf->capacity - iter->buf->size < sizeof(LV2_Event) + ev->size)
const uint16_t total_size = (uint16_t)(sizeof(LV2_Event) + ev->size);
if (iter->buf->capacity - iter->buf->size < total_size)
return false;

LV2_Event* const write_ev = (LV2_Event*)(
(uint8_t*)iter->buf->data + iter->offset);
(uint8_t*)iter->buf->data + iter->offset);

*write_ev = *ev;
memcpy((uint8_t*)write_ev + sizeof(LV2_Event), data, ev->size);
++iter->buf->event_count;

const uint16_t size = lv2_event_pad_size(sizeof(LV2_Event) + ev->size);
iter->buf->size += size;
iter->offset += size;
const uint16_t padded_size = lv2_event_pad_size(total_size);
iter->buf->size += padded_size;
iter->offset += padded_size;

return true;
}


+ 2
- 1
source/modules/distrho/src/lv2/logger.h View File

@@ -1,5 +1,5 @@
/*
Copyright 2012 David Robillard <http://drobilla.net>
Copyright 2012-2013 David Robillard <http://drobilla.net>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -28,6 +28,7 @@
#define LV2_ATOM_LOGGER_H

#include <stdio.h>
#include <string.h>

#include "log.h"



+ 6
- 6
source/modules/distrho/src/lv2/lv2-midifunctions.h View File

@@ -50,7 +50,7 @@ inline double lv2midi_get_event(LV2_MIDIState* state,
}
*timestamp = *(double*)(state->midi->data + state->position);
*size = *(size_t*)(state->midi->data + state->position + sizeof(double));
*size = (uint32_t)*(size_t*)(state->midi->data + state->position + sizeof(double));
*data = state->midi->data + state->position +
sizeof(double) + sizeof(size_t);
return *timestamp;
@@ -64,10 +64,10 @@ inline double lv2midi_step(LV2_MIDIState* state) {
return state->frame_count;
}
state->position += sizeof(double);
state->position += (uint32_t)sizeof(double);
size_t size = *(size_t*)(state->midi->data + state->position);
state->position += sizeof(size_t);
state->position += size;
state->position += (uint32_t)sizeof(size_t);
state->position += (uint32_t)size;
return *(double*)(state->midi->data + state->position);
}

@@ -80,9 +80,9 @@ inline void lv2midi_put_event(LV2_MIDIState* state,
if (state->midi->size + sizeof(double) + sizeof(size_t) + size < state->midi->capacity)
{
*((double*)(state->midi->data + state->midi->size)) = timestamp;
state->midi->size += sizeof(double);
state->midi->size += (uint32_t)sizeof(double);
*((size_t*)(state->midi->data + state->midi->size)) = size;
state->midi->size += sizeof(size_t);
state->midi->size += (uint32_t)sizeof(size_t);
memcpy(state->midi->data + state->midi->size, data, size);

state->midi->size += size;


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

@@ -21,7 +21,7 @@
/**
@file lv2.h
API for the LV2 specification <http://lv2plug.in/ns/lv2core>.
Revision: 6.5
Revision: 12.0
*/

#ifndef LV2_H_INCLUDED
@@ -109,6 +109,7 @@
#define LV2_CORE__port LV2_CORE_PREFIX "port"
#define LV2_CORE__portProperty LV2_CORE_PREFIX "portProperty"
#define LV2_CORE__project LV2_CORE_PREFIX "project"
#define LV2_CORE__prototype LV2_CORE_PREFIX "prototype"
#define LV2_CORE__reportsLatency LV2_CORE_PREFIX "reportsLatency"
#define LV2_CORE__requiredFeature LV2_CORE_PREFIX "requiredFeature"
#define LV2_CORE__sampleRate LV2_CORE_PREFIX "sampleRate"


+ 8
- 6
source/modules/distrho/src/lv2/lv2_external_ui.h View File

@@ -73,17 +73,19 @@ typedef struct _LV2_External_UI_Widget {
*/
typedef struct _LV2_External_UI_Host {
/**
* Callback that plugin UI will call
* when UI (GUI window) is closed by user.
* Callback that plugin UI will call when UI (GUI window) is closed by user.
* This callback will be called during execution of LV2_External_UI_Widget::run()
* (i.e. not from background thread).
*
* After this callback is called, UI is defunct. Host must call
* LV2UI_Descriptor::cleanup(). If host wants to make the UI visible
* again UI must be reinstantiated.
* After this callback is called, UI is defunct. Host must call LV2UI_Descriptor::cleanup().
* If host wants to make the UI visible again, the UI must be reinstantiated.
*
* @note When using the depreated URI LV2_EXTERNAL_UI_DEPRECATED_URI,
* some hosts will not call LV2UI_Descriptor::cleanup() as they should,
* and may call show() again without re-initialization.
*
* @param controller Host context associated with plugin UI, as
* supplied to LV2UI_Descriptor::instantiate()
* supplied to LV2UI_Descriptor::instantiate().
*/
void (*ui_closed)(LV2UI_Controller controller);



+ 14
- 0
source/modules/distrho/src/lv2/lv2_rtmempool.h View File

@@ -27,6 +27,9 @@
/** max size of memory pool name, in chars, including terminating zero char */
#define LV2_RTSAFE_MEMORY_POOL_NAME_MAX 128

/** This extension used to be defined by a different URI */
#define LV2_RTSAFE_MEMORY_POOL_DEPRECATED_URI "http://home.gna.org/lv2dynparam/rtmempool/v1"

#ifdef __cplusplus
extern "C" {
#else
@@ -98,6 +101,17 @@ typedef struct _LV2_RtMemPool_Pool {

} LV2_RtMemPool_Pool;

/**
* Deprecated feature for backwards compatibility.
*/
typedef struct _LV2_RtMemPool_Pool_Deprecated {
unsigned char (*create)(const char*,size_t,size_t,size_t,LV2_RtMemPool_Handle*);
void (*destroy)(LV2_RtMemPool_Handle);
void* (*allocate_atomic)(LV2_RtMemPool_Handle);
void* (*allocate_sleepy)(LV2_RtMemPool_Handle);
void (*deallocate)(LV2_RtMemPool_Handle,void*);
} LV2_RtMemPool_Pool_Deprecated;

#ifdef __cplusplus
} /* extern "C" */
#endif


+ 2
- 2
source/modules/distrho/src/lv2/morph.h View File

@@ -19,8 +19,8 @@

#include <stdint.h>

#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
#include "lv2.h"
#include "urid.h"

#define LV2_MORPH_URI "http://lv2plug.in/ns/ext/morph"
#define LV2_MORPH_PREFIX LV2_MORPH_URI "#"


+ 24
- 23
source/modules/distrho/src/lv2/patch.h View File

@@ -28,28 +28,29 @@
#define LV2_PATCH_URI "http://lv2plug.in/ns/ext/patch"
#define LV2_PATCH_PREFIX LV2_PATCH_URI "#"

#define LV2_PATCH__Ack LV2_PATCH_PREFIX "Ack"
#define LV2_PATCH__Delete LV2_PATCH_PREFIX "Delete"
#define LV2_PATCH__Error LV2_PATCH_PREFIX "Error"
#define LV2_PATCH__Get LV2_PATCH_PREFIX "Get"
#define LV2_PATCH__Message LV2_PATCH_PREFIX "Message"
#define LV2_PATCH__Move LV2_PATCH_PREFIX "Move"
#define LV2_PATCH__Patch LV2_PATCH_PREFIX "Patch"
#define LV2_PATCH__Post LV2_PATCH_PREFIX "Post"
#define LV2_PATCH__Put LV2_PATCH_PREFIX "Put"
#define LV2_PATCH__Request LV2_PATCH_PREFIX "Request"
#define LV2_PATCH__Response LV2_PATCH_PREFIX "Response"
#define LV2_PATCH__Set LV2_PATCH_PREFIX "Set"
#define LV2_PATCH__add LV2_PATCH_PREFIX "add"
#define LV2_PATCH__body LV2_PATCH_PREFIX "body"
#define LV2_PATCH__destination LV2_PATCH_PREFIX "destination"
#define LV2_PATCH__property LV2_PATCH_PREFIX "property"
#define LV2_PATCH__readable LV2_PATCH_PREFIX "readable"
#define LV2_PATCH__remove LV2_PATCH_PREFIX "remove"
#define LV2_PATCH__request LV2_PATCH_PREFIX "request"
#define LV2_PATCH__subject LV2_PATCH_PREFIX "subject"
#define LV2_PATCH__value LV2_PATCH_PREFIX "value"
#define LV2_PATCH__wildcard LV2_PATCH_PREFIX "wildcard"
#define LV2_PATCH__writable LV2_PATCH_PREFIX "writable"
#define LV2_PATCH__Ack LV2_PATCH_PREFIX "Ack"
#define LV2_PATCH__Delete LV2_PATCH_PREFIX "Delete"
#define LV2_PATCH__Error LV2_PATCH_PREFIX "Error"
#define LV2_PATCH__Get LV2_PATCH_PREFIX "Get"
#define LV2_PATCH__Message LV2_PATCH_PREFIX "Message"
#define LV2_PATCH__Move LV2_PATCH_PREFIX "Move"
#define LV2_PATCH__Patch LV2_PATCH_PREFIX "Patch"
#define LV2_PATCH__Post LV2_PATCH_PREFIX "Post"
#define LV2_PATCH__Put LV2_PATCH_PREFIX "Put"
#define LV2_PATCH__Request LV2_PATCH_PREFIX "Request"
#define LV2_PATCH__Response LV2_PATCH_PREFIX "Response"
#define LV2_PATCH__Set LV2_PATCH_PREFIX "Set"
#define LV2_PATCH__add LV2_PATCH_PREFIX "add"
#define LV2_PATCH__body LV2_PATCH_PREFIX "body"
#define LV2_PATCH__destination LV2_PATCH_PREFIX "destination"
#define LV2_PATCH__property LV2_PATCH_PREFIX "property"
#define LV2_PATCH__readable LV2_PATCH_PREFIX "readable"
#define LV2_PATCH__remove LV2_PATCH_PREFIX "remove"
#define LV2_PATCH__request LV2_PATCH_PREFIX "request"
#define LV2_PATCH__subject LV2_PATCH_PREFIX "subject"
#define LV2_PATCH__sequenceNumber LV2_PATCH_PREFIX "sequenceNumber"
#define LV2_PATCH__value LV2_PATCH_PREFIX "value"
#define LV2_PATCH__wildcard LV2_PATCH_PREFIX "wildcard"
#define LV2_PATCH__writable LV2_PATCH_PREFIX "writable"

#endif /* LV2_PATCH_H */

+ 30
- 3
source/modules/distrho/src/lv2/ui.h View File

@@ -1,6 +1,6 @@
/*
LV2 UI Extension
Copyright 2009-2012 David Robillard <d@drobilla.net>
Copyright 2009-2013 David Robillard <d@drobilla.net>
Copyright 2006-2011 Lars Luthman <lars.luthman@gmail.com>

Permission to use, copy, modify, and/or distribute this software for any
@@ -51,8 +51,10 @@
#define LV2_UI__portNotification LV2_UI_PREFIX "portNotification"
#define LV2_UI__portSubscribe LV2_UI_PREFIX "portSubscribe"
#define LV2_UI__resize LV2_UI_PREFIX "resize"
#define LV2_UI__showInterface LV2_UI_PREFIX "showInterface"
#define LV2_UI__touch LV2_UI_PREFIX "touch"
#define LV2_UI__ui LV2_UI_PREFIX "ui"
#define LV2_UI__updateRate LV2_UI_PREFIX "updateRate"

/**
The index returned by LV2_UI_Port_Port::port_index() for unknown ports.
@@ -260,7 +262,7 @@ typedef struct _LV2UI_Port_Map {
/**
Get the index for the port with the given @p symbol.

@return The index of the port, or LV2_UI_INVALID_PORT_INDEX if no such
@return The index of the port, or LV2UI_INVALID_PORT_INDEX if no such
port is found.
*/
uint32_t (*port_index)(LV2UI_Feature_Handle handle, const char* symbol);
@@ -339,7 +341,7 @@ typedef struct _LV2UI_Touch {
} LV2UI_Touch;

/**
UI Idle Feature (LV2_UI__idle)
UI Idle Feature (LV2_UI__idleInterface)

This feature is an addition to the UI API that provides a callback for the
host to call rapidly, e.g. to drive the idle callback of a toolkit.
@@ -356,6 +358,31 @@ typedef struct _LV2UI_Idle_Interface {
int (*idle)(LV2UI_Handle ui);
} LV2UI_Idle_Interface;

/**
UI Show Interface (LV2_UI__showInterface)

UIs can use this interface to provide show/hide methods to pop up a window,
which allows them to function in hosts unable to embed their widget type.

If used, LV2UI_Idle_Interface should also be used to drive the UI. The UI
should return non-zero from idle() when the window has been closed.
*/
typedef struct _LV2UI_Show_Interface {
/**
Show a window for this UI.

@return 0 on success, or anything else to stop being called.
*/
int (*show)(LV2UI_Handle ui);

/**
Hide the window for this UI.

@return 0 on success, or anything else to stop being called.
*/
int (*hide)(LV2UI_Handle ui);
} LV2UI_Show_Interface;

/**
Peak data for a slice of time, the update format for ui:peakProtocol.
*/


+ 1
- 1
source/modules/distrho/src/lv2/uri-map.h View File

@@ -92,7 +92,7 @@ typedef struct {
} LV2_URI_Map_Feature;

#ifdef __cplusplus
} /* extern "C" */
} /* extern "C" */
#endif

#endif /* LV2_URI_MAP_H */

+ 1
- 1
source/modules/distrho/src/lv2/urid.h View File

@@ -123,7 +123,7 @@ typedef struct _LV2_URID_Unmap {
} LV2_URID_Unmap;

#ifdef __cplusplus
} /* extern "C" */
} /* extern "C" */
#endif

#endif /* LV2_URID_H */

+ 1
- 1
source/modules/distrho/src/lv2/worker.h View File

@@ -152,7 +152,7 @@ typedef struct _LV2_Worker_Schedule {
} LV2_Worker_Schedule;

#ifdef __cplusplus
} /* extern "C" */
} /* extern "C" */
#endif

#endif /* LV2_WORKER_H */

+ 1
- 0
source/modules/native-plugins/3bandeq/DistrhoUI3BandEQ.cpp View File

@@ -42,6 +42,7 @@ DistrhoUI3BandEQ::DistrhoUI3BandEQ()
fSliderLow = new ImageSlider(this, sliderImage);
fSliderLow->setStartPos(sliderPosStart);
fSliderLow->setEndPos(sliderPosEnd);
fSliderLow->setInverted(true);
fSliderLow->setRange(-24.0f, 24.0f);
fSliderLow->setValue(0.0f);
fSliderLow->setCallback(this);


+ 1
- 0
source/modules/native-plugins/3bandsplitter/DistrhoUI3BandSplitter.cpp View File

@@ -42,6 +42,7 @@ DistrhoUI3BandSplitter::DistrhoUI3BandSplitter()
fSliderLow = new ImageSlider(this, sliderImage);
fSliderLow->setStartPos(sliderPosStart);
fSliderLow->setEndPos(sliderPosEnd);
fSliderLow->setInverted(true);
fSliderLow->setRange(-24.0f, 24.0f);
fSliderLow->setValue(0.0f);
fSliderLow->setCallback(this);


+ 12
- 15
source/utils/CarlaMutex.hpp View File

@@ -110,9 +110,6 @@ public:
pthread_mutexattr_t atts;
pthread_mutexattr_init(&atts);
pthread_mutexattr_settype(&atts, PTHREAD_MUTEX_RECURSIVE);
# ifndef CARLA_OS_ANDROID
pthread_mutexattr_setprotocol(&atts, PTHREAD_PRIO_INHERIT);
# endif
pthread_mutex_init(&fMutex, &atts);
pthread_mutexattr_destroy(&atts);
#endif
@@ -182,16 +179,16 @@ private:
// Helper class to lock&unlock a mutex during a function scope.

template <class Mutex>
class CarlaScopedLocker
class CarlaScopeLocker
{
public:
CarlaScopedLocker(const Mutex& mutex) noexcept
CarlaScopeLocker(const Mutex& mutex) noexcept
: fMutex(mutex)
{
fMutex.lock();
}

~CarlaScopedLocker() noexcept
~CarlaScopeLocker() noexcept
{
fMutex.unlock();
}
@@ -200,23 +197,23 @@ private:
const Mutex& fMutex;

CARLA_PREVENT_HEAP_ALLOCATION
CARLA_DECLARE_NON_COPY_CLASS(CarlaScopedLocker)
CARLA_DECLARE_NON_COPY_CLASS(CarlaScopeLocker)
};

// -----------------------------------------------------------------------
// Helper class to unlock&lock a mutex during a function scope.

template <class Mutex>
class CarlaScopedUnlocker
class CarlaScopeUnlocker
{
public:
CarlaScopedUnlocker(const Mutex& mutex) noexcept
CarlaScopeUnlocker(const Mutex& mutex) noexcept
: fMutex(mutex)
{
fMutex.unlock();
}

~CarlaScopedUnlocker() noexcept
~CarlaScopeUnlocker() noexcept
{
fMutex.lock();
}
@@ -225,17 +222,17 @@ private:
const Mutex& fMutex;

CARLA_PREVENT_HEAP_ALLOCATION
CARLA_DECLARE_NON_COPY_CLASS(CarlaScopedUnlocker)
CARLA_DECLARE_NON_COPY_CLASS(CarlaScopeUnlocker)
};

// -----------------------------------------------------------------------
// Define types

typedef CarlaScopedLocker<CarlaMutex> CarlaMutexLocker;
typedef CarlaScopedLocker<CarlaRecursiveMutex> CarlaRecursiveMutexLocker;
typedef CarlaScopeLocker<CarlaMutex> CarlaMutexLocker;
typedef CarlaScopeLocker<CarlaRecursiveMutex> CarlaRecursiveMutexLocker;

typedef CarlaScopedUnlocker<CarlaMutex> CarlaMutexUnlocker;
typedef CarlaScopedUnlocker<CarlaRecursiveMutex> CarlaRecursiveMutexUnlocker;
typedef CarlaScopeUnlocker<CarlaMutex> CarlaMutexUnlocker;
typedef CarlaScopeUnlocker<CarlaRecursiveMutex> CarlaRecursiveMutexUnlocker;

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



Loading…
Cancel
Save