Browse Source

Update DPF stuff

tags/1.9.8
falkTX 7 years ago
parent
commit
b08ade977c
23 changed files with 656 additions and 175 deletions
  1. +30
    -30
      data/copy-dpf-stuff
  2. +4
    -4
      source/modules/dgl/NanoVG.hpp
  3. +1
    -1
      source/modules/dgl/Widget.hpp
  4. +8
    -0
      source/modules/dgl/Window.hpp
  5. +2
    -0
      source/modules/dgl/src/Image.cpp
  6. +1
    -1
      source/modules/dgl/src/NanoVG.cpp
  7. +142
    -35
      source/modules/dgl/src/Window.cpp
  8. +2
    -2
      source/modules/dgl/src/pugl/pugl_osx.m
  9. +1
    -1
      source/modules/dgl/src/pugl/pugl_x11.c
  10. +68
    -4
      source/modules/distrho/DistrhoPlugin.hpp
  11. +1
    -1
      source/modules/distrho/DistrhoUtils.hpp
  12. +3
    -3
      source/modules/distrho/extra/ExternalWindow.hpp
  13. +1
    -1
      source/modules/distrho/extra/String.hpp
  14. +2
    -2
      source/modules/distrho/extra/Thread.hpp
  15. +1
    -8
      source/modules/distrho/src/DistrhoDefines.h
  16. +39
    -0
      source/modules/distrho/src/DistrhoPluginInternal.hpp
  17. +105
    -42
      source/modules/distrho/src/DistrhoPluginJack.cpp
  18. +33
    -9
      source/modules/distrho/src/DistrhoPluginLADSPA+DSSI.cpp
  19. +39
    -10
      source/modules/distrho/src/DistrhoPluginLV2.cpp
  20. +69
    -9
      source/modules/distrho/src/DistrhoPluginLV2export.cpp
  21. +80
    -1
      source/modules/distrho/src/DistrhoPluginVST.cpp
  22. +10
    -0
      source/modules/distrho/src/DistrhoUIInternal.hpp
  23. +14
    -11
      source/modules/distrho/src/DistrhoUILV2.cpp

+ 30
- 30
data/copy-dpf-stuff View File

@@ -2,33 +2,33 @@

set -e

# cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/DPF/dgl/*.hpp /home/falktx/FOSS/GIT-mine/Carla/source/modules/dgl/
# cp -r -v /home/falktx/FOSS/GIT-mine/DISTRHO/DPF/dgl/src /home/falktx/FOSS/GIT-mine/Carla/source/modules/dgl/
cp -r -v /home/falktx/FOSS/GIT-mine/DISTRHO/DPF/distrho/* /home/falktx/FOSS/GIT-mine/Carla/source/modules/distrho/
cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/DISTRHO_mini-series/plugins/3BandEQ/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/3bandeq/
cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/DISTRHO_mini-series/plugins/3BandSplitter/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/3bandsplitter/
cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/DISTRHO_mini-series/plugins/PingPongPan/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/pingpongpan/
cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/DISTRHO_nekobi/plugins/Nekobi/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/nekobi/
cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/DISTRHO_nekobi/plugins/Nekobi/nekobee-src/{*.c,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/nekobi/nekobee-src/
cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/DISTRHO_prom/plugins/ProM/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/prom/
cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/GrooveJuice/{*.cpp,*.hpp,*.hxx,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/groovejuice/
cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/PowerJuice/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/powerjuice/
# cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/PowerJuiceX2/{*.cpp,*.hpp,*.hxx,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/powerjuicex2/
cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/SegmentJuice/{*.cpp,*.hpp,*.hxx,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/segmentjuice/
# cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/StutterJuice/{*.cpp,*.hpp,*.hxx,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/stutterjuice/
# cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/TriggerJuice/{*.cpp,*.hpp,*.hxx,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/triggerjuice/
cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/VectorJuice/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/vectorjuice/
cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/WobbleJuice/{*.cpp,*.hpp,*.hxx,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/wobblejuice/
cp -v /home/falktx/FOSS/GIT-mine/zam-plugins-DPF/plugins/ZamComp/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/zamcomp/
cp -v /home/falktx/FOSS/GIT-mine/zam-plugins-DPF/plugins/ZamCompX2/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/zamcompx2/
cp -v /home/falktx/FOSS/GIT-mine/zam-plugins-DPF/plugins/ZamEQ2/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/zameq2/
cp -v /home/falktx/FOSS/GIT-mine/zam-plugins-DPF/plugins/ZamSynth/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/zamsynth/
cp -v /home/falktx/FOSS/GIT-mine/zam-plugins-DPF/plugins/ZamTube/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/zamtube/
cp -v /home/falktx/FOSS/GIT-mine/zam-plugins-DPF/plugins/ZaMultiComp/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/zamulticomp/
cp -v /home/falktx/FOSS/GIT-mine/zam-plugins-DPF/plugins/ZaMultiCompX2/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/Carla/source/modules/native-plugins/zamulticompx2/
cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/DPF/dgl/*.hpp /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/dgl/
cp -r -v /home/falktx/FOSS/GIT-mine/DISTRHO/DPF/dgl/src /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/dgl/
cp -r -v /home/falktx/FOSS/GIT-mine/DISTRHO/DPF/distrho/* /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/distrho/
# cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/DISTRHO_mini-series/plugins/3BandEQ/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/3bandeq/
# cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/DISTRHO_mini-series/plugins/3BandSplitter/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/3bandsplitter/
# cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/DISTRHO_mini-series/plugins/PingPongPan/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/pingpongpan/
#
# cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/DISTRHO_nekobi/plugins/Nekobi/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/nekobi/
# cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/DISTRHO_nekobi/plugins/Nekobi/nekobee-src/{*.c,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/nekobi/nekobee-src/
#
# cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/DISTRHO_prom/plugins/ProM/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/prom/
#
# cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/GrooveJuice/{*.cpp,*.hpp,*.hxx,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/groovejuice/
# cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/PowerJuice/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/powerjuice/
# # cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/PowerJuiceX2/{*.cpp,*.hpp,*.hxx,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/powerjuicex2/
# cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/SegmentJuice/{*.cpp,*.hpp,*.hxx,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/segmentjuice/
# # cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/StutterJuice/{*.cpp,*.hpp,*.hxx,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/stutterjuice/
# # cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/TriggerJuice/{*.cpp,*.hpp,*.hxx,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/triggerjuice/
# cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/VectorJuice/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/vectorjuice/
# cp -v /home/falktx/FOSS/GIT-mine/DISTRHO/JuicePlugins/plugins/WobbleJuice/{*.cpp,*.hpp,*.hxx,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/wobblejuice/
#
# cp -v /home/falktx/FOSS/GIT-mine/zam-plugins-DPF/plugins/ZamComp/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/zamcomp/
# cp -v /home/falktx/FOSS/GIT-mine/zam-plugins-DPF/plugins/ZamCompX2/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/zamcompx2/
# cp -v /home/falktx/FOSS/GIT-mine/zam-plugins-DPF/plugins/ZamEQ2/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/zameq2/
# cp -v /home/falktx/FOSS/GIT-mine/zam-plugins-DPF/plugins/ZamSynth/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/zamsynth/
# cp -v /home/falktx/FOSS/GIT-mine/zam-plugins-DPF/plugins/ZamTube/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/zamtube/
# cp -v /home/falktx/FOSS/GIT-mine/zam-plugins-DPF/plugins/ZaMultiComp/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/zamulticomp/
# cp -v /home/falktx/FOSS/GIT-mine/zam-plugins-DPF/plugins/ZaMultiCompX2/{*.cpp,*.hpp,*.h} /home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/native-plugins/zamulticompx2/

+ 4
- 4
source/modules/dgl/NanoVG.hpp View File

@@ -192,10 +192,10 @@ private:

@code
const char* txt = "Text me up.";
textBounds(vg, x,y, txt, NULL, bounds);
beginPath(vg);
roundedRect(vg, bounds[0], bounds[1], bounds[2]-bounds[0], bounds[3]-bounds[1]);
fill(vg);
vg.textBounds(x,y, txt, NULL, bounds);
vg.beginPath();
vg.roundedRect(bounds[0], bounds[1], bounds[2]-bounds[0], bounds[3]-bounds[1]);
vg.fill();
@endcode

Note: currently only solid color fill is supported for text.


+ 1
- 1
source/modules/dgl/Widget.hpp View File

@@ -111,7 +111,7 @@ public:
/**
Mouse event.
@a button The button number (1 = left, 2 = middle, 3 = right).
@a press True if the key was pressed, false if released.
@a press True if the button was pressed, false if released.
@a pos The widget-relative coordinates of the pointer.
@see onMouse
*/


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

@@ -19,6 +19,10 @@

#include "Geometry.hpp"

START_NAMESPACE_DISTRHO
class UIExporter;
END_NAMESPACE_DISTRHO

START_NAMESPACE_DGL

// -----------------------------------------------------------------------
@@ -125,11 +129,15 @@ private:
friend class Application;
friend class Widget;
friend class StandaloneWindow;
friend class DISTRHO_NAMESPACE::UIExporter;

virtual void _addWidget(Widget* const widget);
virtual void _removeWidget(Widget* const widget);
void _idle();

bool handlePluginKeyboard(const bool press, const uint key);
bool handlePluginSpecial(const bool press, const Key key);

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Window)
};



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

@@ -68,7 +68,9 @@ Image::~Image()
{
if (fTextureId != 0)
{
#ifndef DISTRHO_OS_MAC // FIXME
glDeleteTextures(1, &fTextureId);
#endif
fTextureId = 0;
}
}


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

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


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

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -34,14 +34,12 @@
# include "pugl/pugl_win.cpp"
#elif defined(DISTRHO_OS_MAC)
# include "pugl/pugl_osx.m"
#elif defined(DISTRHO_OS_LINUX)
#else
# include <sys/types.h>
# include <unistd.h>
extern "C" {
# include "pugl/pugl_x11.c"
}
#else
# error Unsupported platform
#endif

#if defined(__GNUC__) && (__GNUC__ >= 7)
@@ -90,13 +88,13 @@ struct Window::PrivateData {
fModal(),
#if defined(DISTRHO_OS_WINDOWS)
hwnd(0)
#elif defined(DISTRHO_OS_LINUX)
xDisplay(nullptr),
xWindow(0)
#elif defined(DISTRHO_OS_MAC)
fNeedsIdle(true),
mView(nullptr),
mWindow(nullptr)
#else
xDisplay(nullptr),
xWindow(0)
#endif
{
DBG("Creating window without parent..."); DBGF;
@@ -118,27 +116,30 @@ struct Window::PrivateData {
fModal(parent.pData),
#if defined(DISTRHO_OS_WINDOWS)
hwnd(0)
#elif defined(DISTRHO_OS_LINUX)
xDisplay(nullptr),
xWindow(0)
#elif defined(DISTRHO_OS_MAC)
fNeedsIdle(false),
mView(nullptr),
mWindow(nullptr)
#else
xDisplay(nullptr),
xWindow(0)
#endif
{
DBG("Creating window with parent..."); DBGF;
init();

const PuglInternals* const parentImpl(parent.pData->fView->impl);
#if defined(DISTRHO_OS_LINUX)
XSetTransientForHint(xDisplay, xWindow, parentImpl->win);
//#elif defined(DISTRHO_OS_MAC)
// [parentImpl->window orderWindow:NSWindowBelow relativeTo:[[mView window] windowNumber]];
#if defined(DISTRHO_OS_WINDOWS)
// TODO
#elif defined(DISTRHO_OS_MAC)
[parentImpl->window orderWindow:NSWindowBelow relativeTo:[[mView window] windowNumber]];
#else
// unused
return; (void)parentImpl;
XSetTransientForHint(xDisplay, xWindow, parentImpl->win);
#endif
return;

// maybe unused
(void)parentImpl;
}

PrivateData(Application& app, Window* const self, const intptr_t parentId)
@@ -156,13 +157,13 @@ struct Window::PrivateData {
fModal(),
#if defined(DISTRHO_OS_WINDOWS)
hwnd(0)
#elif defined(DISTRHO_OS_LINUX)
xDisplay(nullptr),
xWindow(0)
#elif defined(DISTRHO_OS_MAC)
fNeedsIdle(parentId == 0),
mView(nullptr),
mWindow(nullptr)
#else
xDisplay(nullptr),
xWindow(0)
#endif
{
if (fUsingEmbed)
@@ -226,7 +227,7 @@ struct Window::PrivateData {
} else {
DISTRHO_SAFE_ASSERT(mWindow != nullptr);
}
#elif defined(DISTRHO_OS_LINUX)
#else
xDisplay = impl->display;
xWindow = impl->win;
DISTRHO_SAFE_ASSERT(xWindow != 0);
@@ -286,7 +287,7 @@ struct Window::PrivateData {
#elif defined(DISTRHO_OS_MAC)
mView = nullptr;
mWindow = nullptr;
#elif defined(DISTRHO_OS_LINUX)
#else
xDisplay = nullptr;
xWindow = 0;
#endif
@@ -380,7 +381,7 @@ struct Window::PrivateData {
// TODO
#elif defined(DISTRHO_OS_MAC)
// TODO
#elif defined(DISTRHO_OS_LINUX)
#else
int i, wx, wy;
uint u;
::Window w;
@@ -404,7 +405,7 @@ struct Window::PrivateData {
#elif defined(DISTRHO_OS_MAC)
if (mWindow != nullptr)
[mWindow makeKeyWindow];
#elif defined(DISTRHO_OS_LINUX)
#else
XRaiseWindow(xDisplay, xWindow);
XSetInputFocus(xDisplay, xWindow, RevertToPointerRoot, CurrentTime);
XFlush(xDisplay);
@@ -455,7 +456,7 @@ struct Window::PrivateData {
else
[mView setHidden:YES];
}
#elif defined(DISTRHO_OS_LINUX)
#else
if (yesNo)
XMapRaised(xDisplay, xWindow);
else
@@ -559,7 +560,7 @@ struct Window::PrivateData {
[[mWindow standardWindowButton:NSWindowZoomButton] setHidden:YES];
}
}
#elif defined(DISTRHO_OS_LINUX)
#else
XResizeWindow(xDisplay, xWindow, width, height);

if (! fResizable)
@@ -615,7 +616,7 @@ struct Window::PrivateData {

[mWindow setTitle:titleString];
}
#elif defined(DISTRHO_OS_LINUX)
#else
XStoreName(xDisplay, xWindow, title);
#endif
}
@@ -624,14 +625,16 @@ struct Window::PrivateData {
{
DISTRHO_SAFE_ASSERT_RETURN(winId != 0,);

#if defined(DISTRHO_OS_MAC)
NSWindow* window = [NSApp windowWithWindowNumber:winId];
#if defined(DISTRHO_OS_WINDOWS)
// TODO
#elif defined(DISTRHO_OS_MAC)
NSWindow* const window = [NSApp windowWithWindowNumber:winId];
DISTRHO_SAFE_ASSERT_RETURN(window != nullptr,);

[window addChildWindow:mWindow
ordered:NSWindowAbove];
[mWindow makeKeyWindow];
#elif defined(DISTRHO_OS_LINUX)
#else
XSetTransientForHint(xDisplay, xWindow, static_cast< ::Window>(winId));
#endif
}
@@ -859,6 +862,90 @@ struct Window::PrivateData {

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

bool handlePluginKeyboard(const bool press, const uint key)
{
DBGp("PUGL: handlePluginKeyboard : %i %i\n", press, key);

if (fModal.childFocus != nullptr)
{
fModal.childFocus->focus();
return true;
}

Widget::KeyboardEvent ev;
ev.press = press;
ev.key = key;
ev.mod = static_cast<Modifier>(fView->mods);
ev.time = 0;

if ((ev.mod & kModifierShift) != 0 && ev.key >= 'a' && ev.key <= 'z')
ev.key -= 'a' - 'A'; // a-z -> A-Z

FOR_EACH_WIDGET_INV(rit)
{
Widget* const widget(*rit);

if (widget->isVisible() && widget->onKeyboard(ev))
return true;
}

return false;
}

bool handlePluginSpecial(const bool press, const Key key)
{
DBGp("PUGL: handlePluginSpecial : %i %i\n", press, key);

if (fModal.childFocus != nullptr)
{
fModal.childFocus->focus();
return true;
}

int mods = 0x0;

switch (key)
{
case kKeyShift:
mods |= kModifierShift;
break;
case kKeyControl:
mods |= kModifierControl;
break;
case kKeyAlt:
mods |= kModifierAlt;
break;
default:
break;
}

if (mods != 0x0)
{
if (press)
fView->mods |= mods;
else
fView->mods &= ~(mods);
}

Widget::SpecialEvent ev;
ev.press = press;
ev.key = key;
ev.mod = static_cast<Modifier>(fView->mods);
ev.time = 0;

FOR_EACH_WIDGET_INV(rit)
{
Widget* const widget(*rit);

if (widget->isVisible() && widget->onSpecial(ev))
return true;
}

return false;
}

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

Application& fApp;
Window* fSelf;
PuglView* fView;
@@ -898,13 +985,13 @@ struct Window::PrivateData {

#if defined(DISTRHO_OS_WINDOWS)
HWND hwnd;
#elif defined(DISTRHO_OS_LINUX)
Display* xDisplay;
::Window xWindow;
#elif defined(DISTRHO_OS_MAC)
bool fNeedsIdle;
PuglOpenGLView* mView;
id mWindow;
#else
Display* xDisplay;
::Window xWindow;
#endif

// -------------------------------------------------------------------
@@ -1020,7 +1107,7 @@ void Window::repaint() noexcept
#ifndef DGL_FILE_BROWSER_DISABLED
bool Window::openFileBrowser(const FileBrowserOptions& options)
{
#ifdef SOFD_HAVE_X11
# ifdef SOFD_HAVE_X11
using DISTRHO_NAMESPACE::String;

// --------------------------------------------------------------------------
@@ -1078,10 +1165,10 @@ bool Window::openFileBrowser(const FileBrowserOptions& options)
// show

return (x_fib_show(pData->xDisplay, pData->xWindow, /*options.width*/0, /*options.height*/0) == 0);
#else
# else
// not implemented
return false;
#endif
# endif
}
#endif

@@ -1220,6 +1307,26 @@ void Window::fileBrowserSelected(const char*)
}
#endif

bool Window::handlePluginKeyboard(const bool press, const uint key)
{
return pData->handlePluginKeyboard(press, key);
}

bool Window::handlePluginSpecial(const bool press, const Key key)
{
return pData->handlePluginSpecial(press, key);
}

bool Window::handlePluginKeyboard(const bool press, const uint key)
{
return pData->handlePluginKeyboard(press, key);
}

bool Window::handlePluginSpecial(const bool press, const Key key)
{
return pData->handlePluginSpecial(press, key);
}

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

StandaloneWindow::StandaloneWindow()


+ 2
- 2
source/modules/dgl/src/pugl/pugl_osx.m View File

@@ -202,8 +202,6 @@ puglDisplay(PuglView* view)

- (void) reshape
{
[[self openGLContext] update];

if (!puglview) {
/* NOTE: Apparently reshape gets called when the GC gets around to
deleting the view (?), so we must have reset puglview to NULL when
@@ -212,6 +210,8 @@ puglDisplay(PuglView* view)
return;
}

[[self openGLContext] update];

NSRect bounds = [self bounds];
int width = bounds.size.width;
int height = bounds.size.height;


+ 1
- 1
source/modules/dgl/src/pugl/pugl_x11.c View File

@@ -445,7 +445,7 @@ dispatchKey(PuglView* view, XEvent* event, bool press)
view->redisplay = false;
return;
}
if (n == 0) {
if (n == 0 && sym == 0) {
goto send_event;
return;
}


+ 68
- 4
source/modules/distrho/DistrhoPlugin.hpp View File

@@ -133,6 +133,29 @@ struct AudioPort {
symbol() {}
};

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

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

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

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

/**
Parameter ranges.@n
This is used to set the default, minimum and maximum values of a parameter.
@@ -289,6 +312,19 @@ struct Parameter {
*/
ParameterRanges ranges;

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

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

/**
Default constructor for a null parameter.
*/
@@ -297,7 +333,9 @@ struct Parameter {
name(),
symbol(),
unit(),
ranges() {}
ranges(),
designation(kParameterDesignationNull),
midiCC(0) {}

/**
Constructor using custom values.
@@ -307,7 +345,33 @@ struct Parameter {
name(n),
symbol(s),
unit(u),
ranges(def, min, max) {}
ranges(def, min, max),
designation(kParameterDesignationNull),
midiCC(0) {}

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

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

/**
@@ -531,7 +595,7 @@ public:
Returns false when the host buffer is full, in which case do not call this again until the next run().
@note This function is not implemented yet!@n
It's here so that developers can prepare MIDI plugins in advance.@n
If you plan to use this, please report to DPF authos so it can be implemented.
If you plan to use this, please report to DPF authors so it can be implemented.
*/
bool writeMidiEvent(const MidiEvent& midiEvent) noexcept;
#endif
@@ -651,7 +715,7 @@ protected:
/**
Get the value of an internal state.@n
The host may call this function from any non-realtime context.@n
Must be implemented by your plugin class if DISTRHO_PLUGIN_WANT_PROGRAMS or DISTRHO_PLUGIN_WANT_FULL_STATE is enabled.
Must be implemented by your plugin class if DISTRHO_PLUGIN_WANT_FULL_STATE is enabled.
@note The use of this function breaks compatibility with the DSSI format.
*/
virtual String getState(const char* key) const = 0;


+ 1
- 1
source/modules/distrho/DistrhoUtils.hpp View File

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


+ 3
- 3
source/modules/distrho/extra/ExternalWindow.hpp View File

@@ -19,13 +19,13 @@

#include "String.hpp"

#ifdef DISTRHO_OS_UNIX
#ifdef DISTRHO_OS_WINDOWS
# error Unsupported platform!
#else
# include <cerrno>
# include <signal.h>
# include <sys/wait.h>
# include <unistd.h>
#else
# error Unsupported platform!
#endif

START_NAMESPACE_DISTRHO


+ 1
- 1
source/modules/distrho/extra/String.hpp View File

@@ -579,7 +579,7 @@ public:
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";

const std::size_t kTmpBufSize = std::min(d_nextPowerOf2(static_cast<uint32_t>(dataSize/3)), 65536U);
const std::size_t kTmpBufSize = std::min(d_nextPowerOf2(dataSize/3), 65536U);

const uchar* bytesToEncode((const uchar*)data);



+ 2
- 2
source/modules/distrho/extra/Thread.hpp View File

@@ -21,7 +21,7 @@
#include "Sleep.hpp"
#include "String.hpp"

#ifdef DISTRHO_OS_LINUX_FULL
#ifdef DISTRHO_OS_LINUX
# include <sys/prctl.h>
#endif

@@ -198,7 +198,7 @@ public:
{
DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',);

#ifdef DISTRHO_OS_LINUX_FULL
#ifdef DISTRHO_OS_LINUX
prctl(PR_SET_NAME, name, 0, 0, 0);
#endif
#if defined(__GLIBC__) && (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012


+ 1
- 8
source/modules/distrho/src/DistrhoDefines.h View File

@@ -38,17 +38,10 @@
# elif defined(__HAIKU__)
# define DISTRHO_OS_HAIKU 1
# elif defined(__linux__) || defined(__linux)
# define DISTRHO_OS_LINUX 1
# define DISTRHO_OS_LINUX_FULL 1
# elif defined(__FreeBSD__) || defined(__GNU__)
# define DISTRHO_OS_LINUX 1
# define DISTRHO_OS_LINUX 1
# endif
#endif

#if defined(DISTRHO_OS_LINUX) || defined(DISTRHO_OS_MAC)
# define DISTRHO_OS_UNIX
#endif

#ifndef DISTRHO_DLL_EXTENSION
# define DISTRHO_DLL_EXTENSION "so"
#endif


+ 39
- 0
source/modules/distrho/src/DistrhoPluginInternal.hpp View File

@@ -43,6 +43,7 @@ struct Plugin::PrivateData {
#endif

uint32_t parameterCount;
uint32_t parameterOffset;
Parameter* parameters;

#if DISTRHO_PLUGIN_WANT_PROGRAMS
@@ -73,6 +74,7 @@ struct Plugin::PrivateData {
audioPorts(nullptr),
#endif
parameterCount(0),
parameterOffset(0),
parameters(nullptr),
#if DISTRHO_PLUGIN_WANT_PROGRAMS
programCount(0),
@@ -91,6 +93,22 @@ struct Plugin::PrivateData {
{
DISTRHO_SAFE_ASSERT(bufferSize != 0);
DISTRHO_SAFE_ASSERT(d_isNotZero(sampleRate));

#if defined(DISTRHO_PLUGIN_TARGET_DSSI) || defined(DISTRHO_PLUGIN_TARGET_LV2)
parameterOffset += DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS;
# if DISTRHO_PLUGIN_WANT_LATENCY
parameterOffset += 1;
# endif
#endif

#ifdef DISTRHO_PLUGIN_TARGET_LV2
# if (DISTRHO_PLUGIN_IS_SYNTH || DISTRHO_PLUGIN_WANT_TIMEPOS || DISTRHO_PLUGIN_WANT_STATE)
parameterOffset += 1;
# if DISTRHO_PLUGIN_WANT_STATE
parameterOffset += 1;
# endif
# endif
#endif
}

~PrivateData() noexcept
@@ -283,6 +301,13 @@ public:
return fData->parameterCount;
}

uint32_t getParameterOffset() const noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);

return fData->parameterOffset;
}

uint32_t getParameterHints(const uint32_t index) const noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, 0x0);
@@ -290,6 +315,13 @@ public:
return fData->parameters[index].hints;
}

ParameterDesignation getParameterDesignation(const uint32_t index) const noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, kParameterDesignationNull);

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

bool isParameterOutput(const uint32_t index) const noexcept
{
return (getParameterHints(index) & kParameterIsOutput);
@@ -323,6 +355,13 @@ public:
return fData->parameters[index].ranges;
}

uint8_t getParameterMidiCC(const uint32_t index) const noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, 0);

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

float getParameterValue(const uint32_t index) const
{
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0.0f);


+ 105
- 42
source/modules/distrho/src/DistrhoPluginJack.cpp View File

@@ -70,20 +70,14 @@ static void closeSignalHandler(int) noexcept

static void initSignalHandler()
{
struct sigaction sint;
struct sigaction sterm;

sint.sa_handler = closeSignalHandler;
sint.sa_flags = SA_RESTART;
sint.sa_restorer = nullptr;
sigemptyset(&sint.sa_mask);
sigaction(SIGINT, &sint, nullptr);

sterm.sa_handler = closeSignalHandler;
sterm.sa_flags = SA_RESTART;
sterm.sa_restorer = nullptr;
sigemptyset(&sterm.sa_mask);
sigaction(SIGTERM, &sterm, nullptr);
struct sigaction sig;
memset(&sig, 0, sizeof(sig));

sig.sa_handler = closeSignalHandler;
sig.sa_flags = SA_RESTART;
sigemptyset(&sig.sa_mask);
sigaction(SIGINT, &sig, nullptr);
sigaction(SIGTERM, &sig, nullptr);
}
#endif

@@ -103,28 +97,27 @@ public:
#endif
fClient(client)
{
#if DISTRHO_PLUGIN_NUM_INPUTS > 0 || DISTRHO_PLUGIN_NUM_OUTPUTS > 0
char strBuf[0xff+1];
strBuf[0xff] = '\0';

#if DISTRHO_PLUGIN_NUM_INPUTS > 0
# if DISTRHO_PLUGIN_NUM_INPUTS > 0
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i)
{
std::snprintf(strBuf, 0xff, "in%i", i+1);
fPortAudioIns[i] = jack_port_register(fClient, strBuf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
}
#endif

#if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
# endif
# if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i)
{
std::snprintf(strBuf, 0xff, "out%i", i+1);
fPortAudioOuts[i] = jack_port_register(fClient, strBuf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
}
# endif
#endif

#if DISTRHO_PLUGIN_IS_SYNTH
fPortMidiIn = jack_port_register(fClient, "midi-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
#endif
fPortEventsIn = jack_port_register(fClient, "events-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);

#if DISTRHO_PLUGIN_WANT_PROGRAMS
if (fPlugin.getProgramCount() > 0)
@@ -134,11 +127,18 @@ public:
fUI.programLoaded(0);
# endif
}
# if DISTRHO_PLUGIN_HAS_UI
fProgramChanged = -1;
# endif
#endif

if (const uint32_t count = fPlugin.getParameterCount())
{
fLastOutputValues = new float[count];
#if DISTRHO_PLUGIN_HAS_UI
fParametersChanged = new bool[count];
std::memset(fParametersChanged, 0, sizeof(bool)*count);
#endif

for (uint32_t i=0; i < count; ++i)
{
@@ -149,15 +149,18 @@ public:
else
{
fLastOutputValues[i] = 0.0f;
# if DISTRHO_PLUGIN_HAS_UI
#if DISTRHO_PLUGIN_HAS_UI
fUI.parameterChanged(i, fPlugin.getParameterValue(i));
# endif
#endif
}
}
}
else
{
fLastOutputValues = nullptr;
#if DISTRHO_PLUGIN_HAS_UI
fParametersChanged = nullptr;
#endif
}

jack_set_buffer_size_callback(fClient, jackBufferSizeCallback, this);
@@ -198,10 +201,8 @@ public:
if (fClient == nullptr)
return;

#if DISTRHO_PLUGIN_IS_SYNTH
jack_port_unregister(fClient, fPortMidiIn);
fPortMidiIn = nullptr;
#endif
jack_port_unregister(fClient, fPortEventsIn);
fPortEventsIn = nullptr;

#if DISTRHO_PLUGIN_NUM_INPUTS > 0
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i)
@@ -231,20 +232,31 @@ protected:
if (gCloseSignalReceived)
return fUI.quit();

float value;
# if DISTRHO_PLUGIN_WANT_PROGRAMS
if (fProgramChanged >= 0)
{
fUI.programLoaded(fProgramChanged);
fProgramChanged = -1;
}
# endif

for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i)
{
if (! fPlugin.isParameterOutput(i))
continue;

value = fPlugin.getParameterValue(i);
if (fPlugin.isParameterOutput(i))
{
const float value = fPlugin.getParameterValue(i);

if (fLastOutputValues[i] == value)
continue;
if (d_isEqual(fLastOutputValues[i], value))
continue;

fLastOutputValues[i] = value;
fUI.parameterChanged(i, value);
fLastOutputValues[i] = value;
fUI.parameterChanged(i, value);
}
else if (fParametersChanged[i])
{
fParametersChanged[i] = false;
fUI.parameterChanged(i, fPlugin.getParameterValue(i));
}
}

fUI.exec_idle();
@@ -316,14 +328,14 @@ protected:
fPlugin.setTimePosition(fTimePosition);
#endif

#if DISTRHO_PLUGIN_IS_SYNTH
void* const midiBuf = jack_port_get_buffer(fPortMidiIn, nframes);
void* const midiBuf = jack_port_get_buffer(fPortEventsIn, nframes);

if (const uint32_t eventCount = jack_midi_get_event_count(midiBuf))
{
#if DISTRHO_PLUGIN_IS_SYNTH
uint32_t midiEventCount = 0;
MidiEvent midiEvents[eventCount];
#endif
jack_midi_event_t jevent;

for (uint32_t i=0; i < eventCount; ++i)
@@ -331,6 +343,47 @@ protected:
if (jack_midi_event_get(&jevent, midiBuf, i) != 0)
break;

// Check if message is control change on channel 1
if (jevent.buffer[0] == 0xB0 && jevent.size == 3)
{
const uint8_t control = jevent.buffer[1];
const uint8_t value = jevent.buffer[2];

/* NOTE: This is not optimal, we're iterating all parameters on every CC message.
Since the JACK standalone is more of a test tool, this will do for now. */
for (uint32_t j=0, paramCount=fPlugin.getParameterCount(); j < paramCount; ++j)
{
if (fPlugin.isParameterOutput(j))
continue;
if (fPlugin.getParameterMidiCC(j) != control)
continue;

const float scaled = static_cast<float>(value)/127.0f;
const float fvalue = fPlugin.getParameterRanges(j).getUnnormalizedValue(scaled);
fPlugin.setParameterValue(j, fvalue);
#if DISTRHO_PLUGIN_HAS_UI
fParametersChanged[j] = true;
#endif
break;
}
}
#if DISTRHO_PLUGIN_WANT_PROGRAMS
// Check if message is program change on channel 1
else if (jevent.buffer[0] == 0xC0 && jevent.size == 2)
{
const uint8_t program = jevent.buffer[1];

if (program < fPlugin.getProgramCount())
{
fPlugin.loadProgram(program);
# if DISTRHO_PLUGIN_HAS_UI
fProgramChanged = program;
# endif
}
}
#endif

#if DISTRHO_PLUGIN_IS_SYNTH
MidiEvent& midiEvent(midiEvents[midiEventCount++]);

midiEvent.frame = jevent.time;
@@ -340,10 +393,14 @@ protected:
midiEvent.dataExt = jevent.buffer;
else
std::memcpy(midiEvent.data, jevent.buffer, midiEvent.size);
#endif
}

#if DISTRHO_PLUGIN_IS_SYNTH
fPlugin.run(audioIns, audioOuts, nframes, midiEvents, midiEventCount);
#endif
}
#if DISTRHO_PLUGIN_IS_SYNTH
else
{
fPlugin.run(audioIns, audioOuts, nframes, nullptr, 0);
@@ -399,9 +456,7 @@ private:
#if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
jack_port_t* fPortAudioOuts[DISTRHO_PLUGIN_NUM_OUTPUTS];
#endif
#if DISTRHO_PLUGIN_IS_SYNTH
jack_port_t* fPortMidiIn;
#endif
jack_port_t* fPortEventsIn;
#if DISTRHO_PLUGIN_WANT_TIMEPOS
TimePosition fTimePosition;
#endif
@@ -409,6 +464,14 @@ private:
// Temporary data
float* fLastOutputValues;

#if DISTRHO_PLUGIN_HAS_UI
// Store DSP changes to send to UI
bool* fParametersChanged;
# if DISTRHO_PLUGIN_WANT_PROGRAMS
int fProgramChanged;
# endif
#endif

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



+ 33
- 9
source/modules/distrho/src/DistrhoPluginLADSPA+DSSI.cpp View File

@@ -250,17 +250,16 @@ public:
midiEvents[j].data[2] = 0;
midiEvents[j].data[3] = 0;
break;
#if 0 // TODO
case SND_SEQ_EVENT_PITCHBEND:
j = midiEventCount++;
midiEvents[j].frame = seqEvent.time.tick;
midiEvents[j].size = 3;
midiEvents[j].data[0] = 0xE0 + seqEvent.data.control.channel;
midiEvents[j].data[1] = 0;
midiEvents[j].data[2] = 0;
uint16_t tempvalue = seqEvent.data.control.value + 8192;
midiEvents[j].data[1] = tempvalue & 0x7F;
midiEvents[j].data[2] = tempvalue >> 7;
midiEvents[j].data[3] = 0;
break;
#endif
}
}

@@ -329,6 +328,21 @@ public:
}
}
# endif

int dssi_get_midi_controller_for_port(const ulong port) noexcept
{
const uint32_t parameterOffset = fPlugin.getParameterOffset();

if (port > parameterOffset)
return DSSI_NONE;

const uint8_t midiCC = fPlugin.getParameterMidiCC(port-parameterOffset);

if (midiCC == 0 || midiCC == 32 || midiCC >= 0x78)
return DSSI_NONE;

return DSSI_CC(midiCC);
}
#endif

// -------------------------------------------------------------------
@@ -435,6 +449,11 @@ static void dssi_select_program(LADSPA_Handle instance, ulong bank, ulong progra
}
# endif

static int dssi_get_midi_controller_for_port(LADSPA_Handle instance, ulong port)
{
return instancePtr->dssi_get_midi_controller_for_port(port);
}

# if DISTRHO_PLUGIN_WANT_MIDI_INPUT
static void dssi_run_synth(LADSPA_Handle instance, ulong sampleCount, snd_seq_event_t* events, ulong eventCount)
{
@@ -489,7 +508,7 @@ static DSSI_Descriptor sDssiDescriptor = {
/* get_program */ nullptr,
/* select_program */ nullptr,
# endif
/* get_midi_controller_for_port */ nullptr,
dssi_get_midi_controller_for_port,
# if DISTRHO_PLUGIN_WANT_MIDI_INPUT
dssi_run_synth,
# else
@@ -614,11 +633,16 @@ public:
const uint32_t hints(plugin.getParameterHints(i));

if (hints & kParameterIsBoolean)
{
portRangeHints[port].HintDescriptor |= LADSPA_HINT_TOGGLED;
if (hints & kParameterIsInteger)
portRangeHints[port].HintDescriptor |= LADSPA_HINT_INTEGER;
if (hints & kParameterIsLogarithmic)
portRangeHints[port].HintDescriptor |= LADSPA_HINT_LOGARITHMIC;
}
else
{
if (hints & kParameterIsInteger)
portRangeHints[port].HintDescriptor |= LADSPA_HINT_INTEGER;
if (hints & kParameterIsLogarithmic)
portRangeHints[port].HintDescriptor |= LADSPA_HINT_LOGARITHMIC;
}
}
}



+ 39
- 10
source/modules/distrho/src/DistrhoPluginLV2.cpp View File

@@ -30,6 +30,10 @@
#include "lv2/lv2_kxstudio_properties.h"
#include "lv2/lv2_programs.h"

#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
# include "libmodauth.h"
#endif

#ifdef noexcept
# undef noexcept
#endif
@@ -58,6 +62,9 @@ class PluginLv2
public:
PluginLv2(const double sampleRate, const LV2_URID_Map* const uridMap, const LV2_Worker_Schedule* const worker, const bool usingNominal)
: fUsingNominal(usingNominal),
#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
fRunCount(0),
#endif
fPortControls(nullptr),
fLastControlValues(nullptr),
fSampleRate(sampleRate),
@@ -512,6 +519,12 @@ public:
if (fLastControlValues[i] != curValue && ! fPlugin.isParameterOutput(i))
{
fLastControlValues[i] = curValue;

if (fPlugin.getParameterDesignation(i) == kParameterDesignationBypass)
{
curValue = 1.0f - curValue;
}

fPlugin.setParameterValue(i, curValue);
}
}
@@ -519,12 +532,21 @@ public:
// Run plugin
if (sampleCount != 0)
{
#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
fRunCount = mod_license_run_begin(fRunCount, sampleCount);
#endif

#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount, fMidiEvents, midiEventCount);
#else
fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount);
#endif

#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
for (uint32_t i=0; i<DISTRHO_PLUGIN_NUM_OUTPUTS; ++i)
mod_license_run_noise(fRunCount, fPortAudioOuts[i], sampleCount, i);
#endif

#if DISTRHO_PLUGIN_WANT_TIMEPOS
// update timePos for next callback
if (d_isNotZero(fLastPositionData.speed))
@@ -589,10 +611,14 @@ public:
#if DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI
const uint32_t capacity = fPortEventsOut->atom.size;

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

fPortEventsOut->atom.size = sizeof(LV2_Atom_Sequence_Body);
fPortEventsOut->atom.type = fURIDs.atomSequence;
fPortEventsOut->body.unit = 0;
fPortEventsOut->body.pad = 0;

// TODO - MIDI Output

for (uint32_t i=0, count=fPlugin.getStateCount(); i < count; ++i)
@@ -617,15 +643,6 @@ public:
if (sizeof(LV2_Atom_Event) + msgSize > capacity - offset)
break;

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

// reserve msg space
char msgBuf[msgSize];
std::memset(msgBuf, 0, msgSize);
@@ -846,6 +863,10 @@ private:
PluginExporter fPlugin;
const bool fUsingNominal; // if false use maxBlockLength

#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
uint32_t fRunCount;
#endif

// LV2 ports
#if DISTRHO_PLUGIN_NUM_INPUTS > 0
const float* fPortAudioIns[DISTRHO_PLUGIN_NUM_INPUTS];
@@ -1034,6 +1055,10 @@ static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, cons
}
#endif

#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
mod_check_license(features, DISTRHO_PLUGIN_URI);
#endif

d_lastBufferSize = 0;
bool usingNominal = false;

@@ -1193,7 +1218,11 @@ static const void* lv2_extension_data(const char* uri)
return &directaccess;
#endif

#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
return mod_license_interface(uri);
#else
return nullptr;
#endif
}

#undef instancePtr


+ 69
- 9
source/modules/distrho/src/DistrhoPluginLV2export.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2017 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -34,6 +34,10 @@
#include "lv2/lv2_kxstudio_properties.h"
#include "lv2/lv2_programs.h"

#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
# include "mod-license.h"
#endif

#include <fstream>
#include <iostream>

@@ -224,6 +228,9 @@ void lv2_generate_ttl(const char* const basename)
#endif
#if DISTRHO_PLUGIN_WANT_PROGRAMS
pluginString += ",\n <" LV2_PROGRAMS__Interface "> ";
#endif
#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
pluginString += ",\n <" MOD_LICENSE__interface "> ";
#endif
pluginString += ";\n\n";

@@ -241,6 +248,9 @@ void lv2_generate_ttl(const char* const basename)
pluginString += ",\n <" LV2_URID__map "> ";
#if DISTRHO_PLUGIN_WANT_STATE
pluginString += ",\n <" LV2_WORKER__schedule "> ";
#endif
#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
pluginString += ",\n <" MOD_LICENSE__feature "> ";
#endif
pluginString += ";\n\n";

@@ -359,7 +369,7 @@ void lv2_generate_ttl(const char* const basename)
pluginString += " lv2:name \"Latency\" ;\n";
pluginString += " lv2:symbol \"lv2_latency\" ;\n";
pluginString += " lv2:designation lv2:latency ;\n";
pluginString += " lv2:portProperty lv2:reportsLatency, lv2:integer ;\n";
pluginString += " lv2:portProperty lv2:reportsLatency, lv2:integer, <" LV2_PORT_PROPS__notOnGUI "> ;\n";
pluginString += " ] ;\n\n";
++portIndex;
#endif
@@ -377,10 +387,34 @@ void lv2_generate_ttl(const char* const basename)
pluginString += " a lv2:InputPort, lv2:ControlPort ;\n";

pluginString += " lv2:index " + String(portIndex) + " ;\n";
pluginString += " lv2:name \"" + plugin.getParameterName(i) + "\" ;\n";

// symbol
bool designated = false;

// designation
if (! plugin.isParameterOutput(i))
{
switch (plugin.getParameterDesignation(i))
{
case kParameterDesignationNull:
break;
case kParameterDesignationBypass:
designated = true;
pluginString += " lv2:name \"Enabled\" ;\n";
pluginString += " lv2:symbol \"lv2_enabled\" ;\n";
pluginString += " lv2:default 1 ;\n";
pluginString += " lv2:minimum 0 ;\n";
pluginString += " lv2:maximum 1 ;\n";
pluginString += " lv2:portProperty lv2:toggled , lv2:integer ;\n";
pluginString += " lv2:designation lv2:enabled ;\n";
break;
}
}

// name and symbol
if (! designated)
{
pluginString += " lv2:name \"" + plugin.getParameterName(i) + "\" ;\n";

String symbol(plugin.getParameterSymbol(i));

if (symbol.isEmpty())
@@ -390,24 +424,28 @@ void lv2_generate_ttl(const char* const basename)
}

// ranges
if (! designated)
{
const ParameterRanges& ranges(plugin.getParameterRanges(i));

if (plugin.getParameterHints(i) & kParameterIsInteger)
{
pluginString += " lv2:default " + String(int(plugin.getParameterValue(i))) + " ;\n";
if (! plugin.isParameterOutput(i))
pluginString += " lv2:default " + String(int(plugin.getParameterValue(i))) + " ;\n";
pluginString += " lv2:minimum " + String(int(ranges.min)) + " ;\n";
pluginString += " lv2:maximum " + String(int(ranges.max)) + " ;\n";
}
else
{
pluginString += " lv2:default " + String(plugin.getParameterValue(i)) + " ;\n";
if (! plugin.isParameterOutput(i))
pluginString += " lv2:default " + String(plugin.getParameterValue(i)) + " ;\n";
pluginString += " lv2:minimum " + String(ranges.min) + " ;\n";
pluginString += " lv2:maximum " + String(ranges.max) + " ;\n";
}
}

// unit
if (! designated)
{
const String& unit(plugin.getParameterUnit(i));

@@ -453,6 +491,7 @@ void lv2_generate_ttl(const char* const basename)
}

// hints
if (! designated)
{
const uint32_t hints(plugin.getParameterHints(i));

@@ -606,7 +645,18 @@ void lv2_generate_ttl(const char* const basename)

plugin.loadProgram(i);

presetString = "<" DISTRHO_PLUGIN_URI + presetSeparator + "preset" + strBuf + ">\n";
presetString = "<" DISTRHO_PLUGIN_URI + presetSeparator + "preset" + strBuf + ">\n";

# if DISTRHO_PLUGIN_WANT_FULL_STATE
if (numParameters == 0 && numStates == 0)
#else
if (numParameters == 0)
#endif
{
presetString += " .";
presetsString += presetString;
continue;
}

# if DISTRHO_PLUGIN_WANT_FULL_STATE
presetString += " state:state [\n";
@@ -629,12 +679,22 @@ void lv2_generate_ttl(const char* const basename)
presetString += " ] .\n\n";
# endif

bool firstParameter = true;

for (uint32_t j=0; j <numParameters; ++j)
{
if (j == 0)
if (plugin.isParameterOutput(j))
continue;

if (firstParameter)
{
presetString += " lv2:port [\n";
firstParameter = false;
}
else
{
presetString += " [\n";
}

presetString += " lv2:symbol \"" + plugin.getParameterSymbol(j) + "\" ;\n";

@@ -643,7 +703,7 @@ void lv2_generate_ttl(const char* const basename)
else
presetString += " pset:value " + String(plugin.getParameterValue(j)) + " ;\n";

if (j+1 == numParameters)
if (j+1 == numParameters || plugin.isParameterOutput(j+1))
presetString += " ] .\n\n";
else
presetString += " ] ,\n";


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

@@ -52,6 +52,8 @@
#define effGetProgramNameIndexed 29
#define effGetPlugCategory 35
#define effIdle 53
#define effEditKeyDown 59
#define effEditKeyUp 60
#define kPlugCategEffect 1
#define kPlugCategSynth 2
#define kVstVersion 2400
@@ -122,8 +124,20 @@ public:
fEffect(effect),
fUiHelper(uiHelper),
fPlugin(plugin),
fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, setSizeCallback, plugin->getInstancePointer())
fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, setSizeCallback, plugin->getInstancePointer()),
fShouldCaptureVstKeys(false)
{
// FIXME only needed for windows?
//#ifdef DISTRHO_OS_WINDOWS
char strBuf[0xff+1];
std::memset(strBuf, 0, sizeof(char)*(0xff+1));
hostCallback(audioMasterGetProductString, 0, 0, strBuf);
d_stdout("Plugin UI running in '%s'", strBuf);

// TODO make a white-list of needed hosts
if (/*std::strcmp(strBuf, "") == 0*/ true)
fShouldCaptureVstKeys = true;
//#endif
}

// -------------------------------------------------------------------
@@ -167,6 +181,60 @@ public:
}
# endif

int handlePluginKeyEvent(const bool down, int32_t index, const intptr_t value)
{
# if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
if (! fShouldCaptureVstKeys)
return 0;

d_stdout("handlePluginKeyEvent %i %i %li\n", down, index, (long int)value);

int special = 0;
switch (value)
{
// convert some specials to normal keys
case 1: index = kCharBackspace; break;
case 6: index = kCharEscape; break;
case 7: index = ' '; break;
case 22: index = kCharDelete; break;

// handle rest of special keys
case 40: special = kKeyF1; break;
case 41: special = kKeyF2; break;
case 42: special = kKeyF3; break;
case 43: special = kKeyF4; break;
case 44: special = kKeyF5; break;
case 45: special = kKeyF6; break;
case 46: special = kKeyF7; break;
case 47: special = kKeyF8; break;
case 48: special = kKeyF9; break;
case 49: special = kKeyF10; break;
case 50: special = kKeyF11; break;
case 51: special = kKeyF12; break;
case 11: special = kKeyLeft; break;
case 12: special = kKeyUp; break;
case 13: special = kKeyRight; break;
case 14: special = kKeyDown; break;
case 15: special = kKeyPageUp; break;
case 16: special = kKeyPageDown; break;
case 10: special = kKeyHome; break;
case 9: special = kKeyEnd; break;
case 21: special = kKeyInsert; break;
case 54: special = kKeyShift; break;
case 55: special = kKeyControl; break;
case 56: special = kKeyAlt; break;
}

if (special != 0)
return fUI.handlePluginSpecial(down, static_cast<Key>(special));

if (index >= 0)
return fUI.handlePluginKeyboard(down, static_cast<uint>(index));
# endif

return 0;
}

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

protected:
@@ -231,6 +299,7 @@ private:

// Plugin UI
UIExporter fUI;
bool fShouldCaptureVstKeys;

// -------------------------------------------------------------------
// Callbacks
@@ -499,6 +568,16 @@ public:
if (fVstUI != nullptr)
fVstUI->idle();
break;

case effEditKeyDown:
if (fVstUI != nullptr)
return fVstUI->handlePluginKeyEvent(true, index, value);
break;

case effEditKeyUp:
if (fVstUI != nullptr)
return fVstUI->handlePluginKeyEvent(false, index, value);
break;
#endif // DISTRHO_PLUGIN_HAS_UI

#if DISTRHO_PLUGIN_WANT_STATE


+ 10
- 0
source/modules/distrho/src/DistrhoUIInternal.hpp View File

@@ -418,6 +418,16 @@ public:

return ! glApp.isQuiting();
}

bool handlePluginKeyboard(const bool press, const uint key)
{
return glWindow.handlePluginKeyboard(press, key);
}

bool handlePluginSpecial(const bool press, const Key key)
{
return glWindow.handlePluginKeyboard(press, key);
}
#else
void setWindowSize(const uint width, const uint height, const bool updateUI = false) {}
void setWindowTransientWinId(const uintptr_t winId) {}


+ 14
- 11
source/modules/distrho/src/DistrhoUILV2.cpp View File

@@ -23,6 +23,7 @@
#include "lv2/data-access.h"
#include "lv2/instance-access.h"
#include "lv2/options.h"
#include "lv2/parameters.h"
#include "lv2/ui.h"
#include "lv2/urid.h"
#include "lv2/lv2_kxstudio_properties.h"
@@ -114,7 +115,9 @@ public:
{
const uint32_t parameterOffset(fUI.getParameterOffset());

DISTRHO_SAFE_ASSERT_RETURN(rindex >= parameterOffset,)
if (rindex < parameterOffset)
return;

DISTRHO_SAFE_ASSERT_RETURN(bufferSize == sizeof(float),)

const float value(*(const float*)buffer);
@@ -173,17 +176,17 @@ public:
{
for (int i=0; options[i].key != 0; ++i)
{
if (options[i].key == fUridMap->map(fUridMap->handle, LV2_CORE__sampleRate))
if (options[i].key == fUridMap->map(fUridMap->handle, LV2_PARAMETERS__sampleRate))
{
if (options[i].type == fUridMap->map(fUridMap->handle, LV2_ATOM__Double))
if (options[i].type == fUridMap->map(fUridMap->handle, LV2_ATOM__Float))
{
const double sampleRate(*(const double*)options[i].value);
const float sampleRate(*(const float*)options[i].value);
fUI.setSampleRate(sampleRate);
continue;
}
else
{
d_stderr("Host changed sampleRate but with wrong value type");
d_stderr("Host changed UI sample-rate but with wrong value type");
continue;
}
}
@@ -237,7 +240,7 @@ protected:
const size_t msgSize(tmpStr.length()+1);

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

@@ -400,23 +403,23 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* uri,

if (options != nullptr)
{
const LV2_URID uridSampleRate(uridMap->map(uridMap->handle, LV2_CORE__sampleRate));
const LV2_URID uridSampleRate(uridMap->map(uridMap->handle, LV2_PARAMETERS__sampleRate));

for (int i=0; options[i].key != 0; ++i)
{
if (options[i].key == uridSampleRate)
{
if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Double))
d_lastUiSampleRate = *(const double*)options[i].value;
if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Float))
d_lastUiSampleRate = *(const float*)options[i].value;
else
d_stderr("Host provides sampleRate but has wrong value type");
d_stderr("Host provides UI sample-rate but has wrong value type");

break;
}
}
}

if (d_lastUiSampleRate == 0.0)
if (d_lastUiSampleRate < 1.0)
{
d_stdout("WARNING: this host does not send sample-rate information for LV2 UIs, using 44100 as fallback (this could be wrong)");
d_lastUiSampleRate = 44100.0;


Loading…
Cancel
Save