| @@ -2,33 +2,33 @@ | |||||
| set -e | 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/ | |||||
| @@ -192,10 +192,10 @@ private: | |||||
| @code | @code | ||||
| const char* txt = "Text me up."; | 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 | @endcode | ||||
| Note: currently only solid color fill is supported for text. | Note: currently only solid color fill is supported for text. | ||||
| @@ -111,7 +111,7 @@ public: | |||||
| /** | /** | ||||
| Mouse event. | Mouse event. | ||||
| @a button The button number (1 = left, 2 = middle, 3 = right). | @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. | @a pos The widget-relative coordinates of the pointer. | ||||
| @see onMouse | @see onMouse | ||||
| */ | */ | ||||
| @@ -19,6 +19,10 @@ | |||||
| #include "Geometry.hpp" | #include "Geometry.hpp" | ||||
| START_NAMESPACE_DISTRHO | |||||
| class UIExporter; | |||||
| END_NAMESPACE_DISTRHO | |||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -125,11 +129,15 @@ private: | |||||
| friend class Application; | friend class Application; | ||||
| friend class Widget; | friend class Widget; | ||||
| friend class StandaloneWindow; | friend class StandaloneWindow; | ||||
| friend class DISTRHO_NAMESPACE::UIExporter; | |||||
| virtual void _addWidget(Widget* const widget); | virtual void _addWidget(Widget* const widget); | ||||
| virtual void _removeWidget(Widget* const widget); | virtual void _removeWidget(Widget* const widget); | ||||
| void _idle(); | 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) | DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Window) | ||||
| }; | }; | ||||
| @@ -68,7 +68,9 @@ Image::~Image() | |||||
| { | { | ||||
| if (fTextureId != 0) | if (fTextureId != 0) | ||||
| { | { | ||||
| #ifndef DISTRHO_OS_MAC // FIXME | |||||
| glDeleteTextures(1, &fTextureId); | glDeleteTextures(1, &fTextureId); | ||||
| #endif | |||||
| fTextureId = 0; | fTextureId = 0; | ||||
| } | } | ||||
| } | } | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * 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 | * 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 | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * 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 | * 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 | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -34,14 +34,12 @@ | |||||
| # include "pugl/pugl_win.cpp" | # include "pugl/pugl_win.cpp" | ||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| # include "pugl/pugl_osx.m" | # include "pugl/pugl_osx.m" | ||||
| #elif defined(DISTRHO_OS_LINUX) | |||||
| #else | |||||
| # include <sys/types.h> | # include <sys/types.h> | ||||
| # include <unistd.h> | # include <unistd.h> | ||||
| extern "C" { | extern "C" { | ||||
| # include "pugl/pugl_x11.c" | # include "pugl/pugl_x11.c" | ||||
| } | } | ||||
| #else | |||||
| # error Unsupported platform | |||||
| #endif | #endif | ||||
| #if defined(__GNUC__) && (__GNUC__ >= 7) | #if defined(__GNUC__) && (__GNUC__ >= 7) | ||||
| @@ -90,13 +88,13 @@ struct Window::PrivateData { | |||||
| fModal(), | fModal(), | ||||
| #if defined(DISTRHO_OS_WINDOWS) | #if defined(DISTRHO_OS_WINDOWS) | ||||
| hwnd(0) | hwnd(0) | ||||
| #elif defined(DISTRHO_OS_LINUX) | |||||
| xDisplay(nullptr), | |||||
| xWindow(0) | |||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| fNeedsIdle(true), | fNeedsIdle(true), | ||||
| mView(nullptr), | mView(nullptr), | ||||
| mWindow(nullptr) | mWindow(nullptr) | ||||
| #else | |||||
| xDisplay(nullptr), | |||||
| xWindow(0) | |||||
| #endif | #endif | ||||
| { | { | ||||
| DBG("Creating window without parent..."); DBGF; | DBG("Creating window without parent..."); DBGF; | ||||
| @@ -118,27 +116,30 @@ struct Window::PrivateData { | |||||
| fModal(parent.pData), | fModal(parent.pData), | ||||
| #if defined(DISTRHO_OS_WINDOWS) | #if defined(DISTRHO_OS_WINDOWS) | ||||
| hwnd(0) | hwnd(0) | ||||
| #elif defined(DISTRHO_OS_LINUX) | |||||
| xDisplay(nullptr), | |||||
| xWindow(0) | |||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| fNeedsIdle(false), | fNeedsIdle(false), | ||||
| mView(nullptr), | mView(nullptr), | ||||
| mWindow(nullptr) | mWindow(nullptr) | ||||
| #else | |||||
| xDisplay(nullptr), | |||||
| xWindow(0) | |||||
| #endif | #endif | ||||
| { | { | ||||
| DBG("Creating window with parent..."); DBGF; | DBG("Creating window with parent..."); DBGF; | ||||
| init(); | init(); | ||||
| const PuglInternals* const parentImpl(parent.pData->fView->impl); | 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 | #else | ||||
| // unused | |||||
| return; (void)parentImpl; | |||||
| XSetTransientForHint(xDisplay, xWindow, parentImpl->win); | |||||
| #endif | #endif | ||||
| return; | |||||
| // maybe unused | |||||
| (void)parentImpl; | |||||
| } | } | ||||
| PrivateData(Application& app, Window* const self, const intptr_t parentId) | PrivateData(Application& app, Window* const self, const intptr_t parentId) | ||||
| @@ -156,13 +157,13 @@ struct Window::PrivateData { | |||||
| fModal(), | fModal(), | ||||
| #if defined(DISTRHO_OS_WINDOWS) | #if defined(DISTRHO_OS_WINDOWS) | ||||
| hwnd(0) | hwnd(0) | ||||
| #elif defined(DISTRHO_OS_LINUX) | |||||
| xDisplay(nullptr), | |||||
| xWindow(0) | |||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| fNeedsIdle(parentId == 0), | fNeedsIdle(parentId == 0), | ||||
| mView(nullptr), | mView(nullptr), | ||||
| mWindow(nullptr) | mWindow(nullptr) | ||||
| #else | |||||
| xDisplay(nullptr), | |||||
| xWindow(0) | |||||
| #endif | #endif | ||||
| { | { | ||||
| if (fUsingEmbed) | if (fUsingEmbed) | ||||
| @@ -226,7 +227,7 @@ struct Window::PrivateData { | |||||
| } else { | } else { | ||||
| DISTRHO_SAFE_ASSERT(mWindow != nullptr); | DISTRHO_SAFE_ASSERT(mWindow != nullptr); | ||||
| } | } | ||||
| #elif defined(DISTRHO_OS_LINUX) | |||||
| #else | |||||
| xDisplay = impl->display; | xDisplay = impl->display; | ||||
| xWindow = impl->win; | xWindow = impl->win; | ||||
| DISTRHO_SAFE_ASSERT(xWindow != 0); | DISTRHO_SAFE_ASSERT(xWindow != 0); | ||||
| @@ -286,7 +287,7 @@ struct Window::PrivateData { | |||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| mView = nullptr; | mView = nullptr; | ||||
| mWindow = nullptr; | mWindow = nullptr; | ||||
| #elif defined(DISTRHO_OS_LINUX) | |||||
| #else | |||||
| xDisplay = nullptr; | xDisplay = nullptr; | ||||
| xWindow = 0; | xWindow = 0; | ||||
| #endif | #endif | ||||
| @@ -380,7 +381,7 @@ struct Window::PrivateData { | |||||
| // TODO | // TODO | ||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| // TODO | // TODO | ||||
| #elif defined(DISTRHO_OS_LINUX) | |||||
| #else | |||||
| int i, wx, wy; | int i, wx, wy; | ||||
| uint u; | uint u; | ||||
| ::Window w; | ::Window w; | ||||
| @@ -404,7 +405,7 @@ struct Window::PrivateData { | |||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| if (mWindow != nullptr) | if (mWindow != nullptr) | ||||
| [mWindow makeKeyWindow]; | [mWindow makeKeyWindow]; | ||||
| #elif defined(DISTRHO_OS_LINUX) | |||||
| #else | |||||
| XRaiseWindow(xDisplay, xWindow); | XRaiseWindow(xDisplay, xWindow); | ||||
| XSetInputFocus(xDisplay, xWindow, RevertToPointerRoot, CurrentTime); | XSetInputFocus(xDisplay, xWindow, RevertToPointerRoot, CurrentTime); | ||||
| XFlush(xDisplay); | XFlush(xDisplay); | ||||
| @@ -455,7 +456,7 @@ struct Window::PrivateData { | |||||
| else | else | ||||
| [mView setHidden:YES]; | [mView setHidden:YES]; | ||||
| } | } | ||||
| #elif defined(DISTRHO_OS_LINUX) | |||||
| #else | |||||
| if (yesNo) | if (yesNo) | ||||
| XMapRaised(xDisplay, xWindow); | XMapRaised(xDisplay, xWindow); | ||||
| else | else | ||||
| @@ -559,7 +560,7 @@ struct Window::PrivateData { | |||||
| [[mWindow standardWindowButton:NSWindowZoomButton] setHidden:YES]; | [[mWindow standardWindowButton:NSWindowZoomButton] setHidden:YES]; | ||||
| } | } | ||||
| } | } | ||||
| #elif defined(DISTRHO_OS_LINUX) | |||||
| #else | |||||
| XResizeWindow(xDisplay, xWindow, width, height); | XResizeWindow(xDisplay, xWindow, width, height); | ||||
| if (! fResizable) | if (! fResizable) | ||||
| @@ -615,7 +616,7 @@ struct Window::PrivateData { | |||||
| [mWindow setTitle:titleString]; | [mWindow setTitle:titleString]; | ||||
| } | } | ||||
| #elif defined(DISTRHO_OS_LINUX) | |||||
| #else | |||||
| XStoreName(xDisplay, xWindow, title); | XStoreName(xDisplay, xWindow, title); | ||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -624,14 +625,16 @@ struct Window::PrivateData { | |||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(winId != 0,); | 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,); | DISTRHO_SAFE_ASSERT_RETURN(window != nullptr,); | ||||
| [window addChildWindow:mWindow | [window addChildWindow:mWindow | ||||
| ordered:NSWindowAbove]; | ordered:NSWindowAbove]; | ||||
| [mWindow makeKeyWindow]; | [mWindow makeKeyWindow]; | ||||
| #elif defined(DISTRHO_OS_LINUX) | |||||
| #else | |||||
| XSetTransientForHint(xDisplay, xWindow, static_cast< ::Window>(winId)); | XSetTransientForHint(xDisplay, xWindow, static_cast< ::Window>(winId)); | ||||
| #endif | #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; | Application& fApp; | ||||
| Window* fSelf; | Window* fSelf; | ||||
| PuglView* fView; | PuglView* fView; | ||||
| @@ -898,13 +985,13 @@ struct Window::PrivateData { | |||||
| #if defined(DISTRHO_OS_WINDOWS) | #if defined(DISTRHO_OS_WINDOWS) | ||||
| HWND hwnd; | HWND hwnd; | ||||
| #elif defined(DISTRHO_OS_LINUX) | |||||
| Display* xDisplay; | |||||
| ::Window xWindow; | |||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| bool fNeedsIdle; | bool fNeedsIdle; | ||||
| PuglOpenGLView* mView; | PuglOpenGLView* mView; | ||||
| id mWindow; | id mWindow; | ||||
| #else | |||||
| Display* xDisplay; | |||||
| ::Window xWindow; | |||||
| #endif | #endif | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -1020,7 +1107,7 @@ void Window::repaint() noexcept | |||||
| #ifndef DGL_FILE_BROWSER_DISABLED | #ifndef DGL_FILE_BROWSER_DISABLED | ||||
| bool Window::openFileBrowser(const FileBrowserOptions& options) | bool Window::openFileBrowser(const FileBrowserOptions& options) | ||||
| { | { | ||||
| #ifdef SOFD_HAVE_X11 | |||||
| # ifdef SOFD_HAVE_X11 | |||||
| using DISTRHO_NAMESPACE::String; | using DISTRHO_NAMESPACE::String; | ||||
| // -------------------------------------------------------------------------- | // -------------------------------------------------------------------------- | ||||
| @@ -1078,10 +1165,10 @@ bool Window::openFileBrowser(const FileBrowserOptions& options) | |||||
| // show | // show | ||||
| return (x_fib_show(pData->xDisplay, pData->xWindow, /*options.width*/0, /*options.height*/0) == 0); | return (x_fib_show(pData->xDisplay, pData->xWindow, /*options.width*/0, /*options.height*/0) == 0); | ||||
| #else | |||||
| # else | |||||
| // not implemented | // not implemented | ||||
| return false; | return false; | ||||
| #endif | |||||
| # endif | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -1220,6 +1307,26 @@ void Window::fileBrowserSelected(const char*) | |||||
| } | } | ||||
| #endif | #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() | StandaloneWindow::StandaloneWindow() | ||||
| @@ -202,8 +202,6 @@ puglDisplay(PuglView* view) | |||||
| - (void) reshape | - (void) reshape | ||||
| { | { | ||||
| [[self openGLContext] update]; | |||||
| if (!puglview) { | if (!puglview) { | ||||
| /* NOTE: Apparently reshape gets called when the GC gets around to | /* NOTE: Apparently reshape gets called when the GC gets around to | ||||
| deleting the view (?), so we must have reset puglview to NULL when | deleting the view (?), so we must have reset puglview to NULL when | ||||
| @@ -212,6 +210,8 @@ puglDisplay(PuglView* view) | |||||
| return; | return; | ||||
| } | } | ||||
| [[self openGLContext] update]; | |||||
| NSRect bounds = [self bounds]; | NSRect bounds = [self bounds]; | ||||
| int width = bounds.size.width; | int width = bounds.size.width; | ||||
| int height = bounds.size.height; | int height = bounds.size.height; | ||||
| @@ -445,7 +445,7 @@ dispatchKey(PuglView* view, XEvent* event, bool press) | |||||
| view->redisplay = false; | view->redisplay = false; | ||||
| return; | return; | ||||
| } | } | ||||
| if (n == 0) { | |||||
| if (n == 0 && sym == 0) { | |||||
| goto send_event; | goto send_event; | ||||
| return; | return; | ||||
| } | } | ||||
| @@ -133,6 +133,29 @@ struct AudioPort { | |||||
| symbol() {} | 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 | Parameter ranges.@n | ||||
| This is used to set the default, minimum and maximum values of a parameter. | This is used to set the default, minimum and maximum values of a parameter. | ||||
| @@ -289,6 +312,19 @@ struct Parameter { | |||||
| */ | */ | ||||
| ParameterRanges ranges; | 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. | Default constructor for a null parameter. | ||||
| */ | */ | ||||
| @@ -297,7 +333,9 @@ struct Parameter { | |||||
| name(), | name(), | ||||
| symbol(), | symbol(), | ||||
| unit(), | unit(), | ||||
| ranges() {} | |||||
| ranges(), | |||||
| designation(kParameterDesignationNull), | |||||
| midiCC(0) {} | |||||
| /** | /** | ||||
| Constructor using custom values. | Constructor using custom values. | ||||
| @@ -307,7 +345,33 @@ struct Parameter { | |||||
| name(n), | name(n), | ||||
| symbol(s), | symbol(s), | ||||
| unit(u), | 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(). | 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 | @note This function is not implemented yet!@n | ||||
| It's here so that developers can prepare MIDI plugins in advance.@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; | bool writeMidiEvent(const MidiEvent& midiEvent) noexcept; | ||||
| #endif | #endif | ||||
| @@ -651,7 +715,7 @@ protected: | |||||
| /** | /** | ||||
| Get the value of an internal state.@n | Get the value of an internal state.@n | ||||
| The host may call this function from any non-realtime context.@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. | @note The use of this function breaks compatibility with the DSSI format. | ||||
| */ | */ | ||||
| virtual String getState(const char* key) const = 0; | virtual String getState(const char* key) const = 0; | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * 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 | * 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 | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -19,13 +19,13 @@ | |||||
| #include "String.hpp" | #include "String.hpp" | ||||
| #ifdef DISTRHO_OS_UNIX | |||||
| #ifdef DISTRHO_OS_WINDOWS | |||||
| # error Unsupported platform! | |||||
| #else | |||||
| # include <cerrno> | # include <cerrno> | ||||
| # include <signal.h> | # include <signal.h> | ||||
| # include <sys/wait.h> | # include <sys/wait.h> | ||||
| # include <unistd.h> | # include <unistd.h> | ||||
| #else | |||||
| # error Unsupported platform! | |||||
| #endif | #endif | ||||
| START_NAMESPACE_DISTRHO | START_NAMESPACE_DISTRHO | ||||
| @@ -579,7 +579,7 @@ public: | |||||
| "abcdefghijklmnopqrstuvwxyz" | "abcdefghijklmnopqrstuvwxyz" | ||||
| "0123456789+/"; | "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); | const uchar* bytesToEncode((const uchar*)data); | ||||
| @@ -21,7 +21,7 @@ | |||||
| #include "Sleep.hpp" | #include "Sleep.hpp" | ||||
| #include "String.hpp" | #include "String.hpp" | ||||
| #ifdef DISTRHO_OS_LINUX_FULL | |||||
| #ifdef DISTRHO_OS_LINUX | |||||
| # include <sys/prctl.h> | # include <sys/prctl.h> | ||||
| #endif | #endif | ||||
| @@ -198,7 +198,7 @@ public: | |||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); | 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); | prctl(PR_SET_NAME, name, 0, 0, 0); | ||||
| #endif | #endif | ||||
| #if defined(__GLIBC__) && (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012 | #if defined(__GLIBC__) && (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012 | ||||
| @@ -38,17 +38,10 @@ | |||||
| # elif defined(__HAIKU__) | # elif defined(__HAIKU__) | ||||
| # define DISTRHO_OS_HAIKU 1 | # define DISTRHO_OS_HAIKU 1 | ||||
| # elif defined(__linux__) || defined(__linux) | # 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 | ||||
| #endif | #endif | ||||
| #if defined(DISTRHO_OS_LINUX) || defined(DISTRHO_OS_MAC) | |||||
| # define DISTRHO_OS_UNIX | |||||
| #endif | |||||
| #ifndef DISTRHO_DLL_EXTENSION | #ifndef DISTRHO_DLL_EXTENSION | ||||
| # define DISTRHO_DLL_EXTENSION "so" | # define DISTRHO_DLL_EXTENSION "so" | ||||
| #endif | #endif | ||||
| @@ -43,6 +43,7 @@ struct Plugin::PrivateData { | |||||
| #endif | #endif | ||||
| uint32_t parameterCount; | uint32_t parameterCount; | ||||
| uint32_t parameterOffset; | |||||
| Parameter* parameters; | Parameter* parameters; | ||||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | #if DISTRHO_PLUGIN_WANT_PROGRAMS | ||||
| @@ -73,6 +74,7 @@ struct Plugin::PrivateData { | |||||
| audioPorts(nullptr), | audioPorts(nullptr), | ||||
| #endif | #endif | ||||
| parameterCount(0), | parameterCount(0), | ||||
| parameterOffset(0), | |||||
| parameters(nullptr), | parameters(nullptr), | ||||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | #if DISTRHO_PLUGIN_WANT_PROGRAMS | ||||
| programCount(0), | programCount(0), | ||||
| @@ -91,6 +93,22 @@ struct Plugin::PrivateData { | |||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT(bufferSize != 0); | DISTRHO_SAFE_ASSERT(bufferSize != 0); | ||||
| DISTRHO_SAFE_ASSERT(d_isNotZero(sampleRate)); | 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 | ~PrivateData() noexcept | ||||
| @@ -283,6 +301,13 @@ public: | |||||
| return fData->parameterCount; | 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 | uint32_t getParameterHints(const uint32_t index) const noexcept | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, 0x0); | DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, 0x0); | ||||
| @@ -290,6 +315,13 @@ public: | |||||
| return fData->parameters[index].hints; | 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 | bool isParameterOutput(const uint32_t index) const noexcept | ||||
| { | { | ||||
| return (getParameterHints(index) & kParameterIsOutput); | return (getParameterHints(index) & kParameterIsOutput); | ||||
| @@ -323,6 +355,13 @@ public: | |||||
| return fData->parameters[index].ranges; | 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 | float getParameterValue(const uint32_t index) const | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0.0f); | DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0.0f); | ||||
| @@ -70,20 +70,14 @@ static void closeSignalHandler(int) noexcept | |||||
| static void initSignalHandler() | 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 | #endif | ||||
| @@ -103,28 +97,27 @@ public: | |||||
| #endif | #endif | ||||
| fClient(client) | fClient(client) | ||||
| { | { | ||||
| #if DISTRHO_PLUGIN_NUM_INPUTS > 0 || DISTRHO_PLUGIN_NUM_OUTPUTS > 0 | |||||
| char strBuf[0xff+1]; | char strBuf[0xff+1]; | ||||
| strBuf[0xff] = '\0'; | 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) | for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i) | ||||
| { | { | ||||
| std::snprintf(strBuf, 0xff, "in%i", i+1); | std::snprintf(strBuf, 0xff, "in%i", i+1); | ||||
| fPortAudioIns[i] = jack_port_register(fClient, strBuf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); | 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) | for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i) | ||||
| { | { | ||||
| std::snprintf(strBuf, 0xff, "out%i", i+1); | std::snprintf(strBuf, 0xff, "out%i", i+1); | ||||
| fPortAudioOuts[i] = jack_port_register(fClient, strBuf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | fPortAudioOuts[i] = jack_port_register(fClient, strBuf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | ||||
| } | } | ||||
| # endif | |||||
| #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 DISTRHO_PLUGIN_WANT_PROGRAMS | ||||
| if (fPlugin.getProgramCount() > 0) | if (fPlugin.getProgramCount() > 0) | ||||
| @@ -134,11 +127,18 @@ public: | |||||
| fUI.programLoaded(0); | fUI.programLoaded(0); | ||||
| # endif | # endif | ||||
| } | } | ||||
| # if DISTRHO_PLUGIN_HAS_UI | |||||
| fProgramChanged = -1; | |||||
| # endif | |||||
| #endif | #endif | ||||
| if (const uint32_t count = fPlugin.getParameterCount()) | if (const uint32_t count = fPlugin.getParameterCount()) | ||||
| { | { | ||||
| fLastOutputValues = new float[count]; | 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) | for (uint32_t i=0; i < count; ++i) | ||||
| { | { | ||||
| @@ -149,15 +149,18 @@ public: | |||||
| else | else | ||||
| { | { | ||||
| fLastOutputValues[i] = 0.0f; | fLastOutputValues[i] = 0.0f; | ||||
| # if DISTRHO_PLUGIN_HAS_UI | |||||
| #if DISTRHO_PLUGIN_HAS_UI | |||||
| fUI.parameterChanged(i, fPlugin.getParameterValue(i)); | fUI.parameterChanged(i, fPlugin.getParameterValue(i)); | ||||
| # endif | |||||
| #endif | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| fLastOutputValues = nullptr; | fLastOutputValues = nullptr; | ||||
| #if DISTRHO_PLUGIN_HAS_UI | |||||
| fParametersChanged = nullptr; | |||||
| #endif | |||||
| } | } | ||||
| jack_set_buffer_size_callback(fClient, jackBufferSizeCallback, this); | jack_set_buffer_size_callback(fClient, jackBufferSizeCallback, this); | ||||
| @@ -198,10 +201,8 @@ public: | |||||
| if (fClient == nullptr) | if (fClient == nullptr) | ||||
| return; | 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 | #if DISTRHO_PLUGIN_NUM_INPUTS > 0 | ||||
| for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i) | for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i) | ||||
| @@ -231,20 +232,31 @@ protected: | |||||
| if (gCloseSignalReceived) | if (gCloseSignalReceived) | ||||
| return fUI.quit(); | 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) | 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(); | fUI.exec_idle(); | ||||
| @@ -316,14 +328,14 @@ protected: | |||||
| fPlugin.setTimePosition(fTimePosition); | fPlugin.setTimePosition(fTimePosition); | ||||
| #endif | #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 (const uint32_t eventCount = jack_midi_get_event_count(midiBuf)) | ||||
| { | { | ||||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||||
| uint32_t midiEventCount = 0; | uint32_t midiEventCount = 0; | ||||
| MidiEvent midiEvents[eventCount]; | MidiEvent midiEvents[eventCount]; | ||||
| #endif | |||||
| jack_midi_event_t jevent; | jack_midi_event_t jevent; | ||||
| for (uint32_t i=0; i < eventCount; ++i) | for (uint32_t i=0; i < eventCount; ++i) | ||||
| @@ -331,6 +343,47 @@ protected: | |||||
| if (jack_midi_event_get(&jevent, midiBuf, i) != 0) | if (jack_midi_event_get(&jevent, midiBuf, i) != 0) | ||||
| break; | 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& midiEvent(midiEvents[midiEventCount++]); | ||||
| midiEvent.frame = jevent.time; | midiEvent.frame = jevent.time; | ||||
| @@ -340,10 +393,14 @@ protected: | |||||
| midiEvent.dataExt = jevent.buffer; | midiEvent.dataExt = jevent.buffer; | ||||
| else | else | ||||
| std::memcpy(midiEvent.data, jevent.buffer, midiEvent.size); | std::memcpy(midiEvent.data, jevent.buffer, midiEvent.size); | ||||
| #endif | |||||
| } | } | ||||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||||
| fPlugin.run(audioIns, audioOuts, nframes, midiEvents, midiEventCount); | fPlugin.run(audioIns, audioOuts, nframes, midiEvents, midiEventCount); | ||||
| #endif | |||||
| } | } | ||||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||||
| else | else | ||||
| { | { | ||||
| fPlugin.run(audioIns, audioOuts, nframes, nullptr, 0); | fPlugin.run(audioIns, audioOuts, nframes, nullptr, 0); | ||||
| @@ -399,9 +456,7 @@ private: | |||||
| #if DISTRHO_PLUGIN_NUM_OUTPUTS > 0 | #if DISTRHO_PLUGIN_NUM_OUTPUTS > 0 | ||||
| jack_port_t* fPortAudioOuts[DISTRHO_PLUGIN_NUM_OUTPUTS]; | jack_port_t* fPortAudioOuts[DISTRHO_PLUGIN_NUM_OUTPUTS]; | ||||
| #endif | #endif | ||||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||||
| jack_port_t* fPortMidiIn; | |||||
| #endif | |||||
| jack_port_t* fPortEventsIn; | |||||
| #if DISTRHO_PLUGIN_WANT_TIMEPOS | #if DISTRHO_PLUGIN_WANT_TIMEPOS | ||||
| TimePosition fTimePosition; | TimePosition fTimePosition; | ||||
| #endif | #endif | ||||
| @@ -409,6 +464,14 @@ private: | |||||
| // Temporary data | // Temporary data | ||||
| float* fLastOutputValues; | 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 | // Callbacks | ||||
| @@ -250,17 +250,16 @@ public: | |||||
| midiEvents[j].data[2] = 0; | midiEvents[j].data[2] = 0; | ||||
| midiEvents[j].data[3] = 0; | midiEvents[j].data[3] = 0; | ||||
| break; | break; | ||||
| #if 0 // TODO | |||||
| case SND_SEQ_EVENT_PITCHBEND: | case SND_SEQ_EVENT_PITCHBEND: | ||||
| j = midiEventCount++; | j = midiEventCount++; | ||||
| midiEvents[j].frame = seqEvent.time.tick; | midiEvents[j].frame = seqEvent.time.tick; | ||||
| midiEvents[j].size = 3; | midiEvents[j].size = 3; | ||||
| midiEvents[j].data[0] = 0xE0 + seqEvent.data.control.channel; | 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; | midiEvents[j].data[3] = 0; | ||||
| break; | break; | ||||
| #endif | |||||
| } | } | ||||
| } | } | ||||
| @@ -329,6 +328,21 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| # endif | # 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 | #endif | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -435,6 +449,11 @@ static void dssi_select_program(LADSPA_Handle instance, ulong bank, ulong progra | |||||
| } | } | ||||
| # endif | # 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 | # if DISTRHO_PLUGIN_WANT_MIDI_INPUT | ||||
| static void dssi_run_synth(LADSPA_Handle instance, ulong sampleCount, snd_seq_event_t* events, ulong eventCount) | 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, | /* get_program */ nullptr, | ||||
| /* select_program */ nullptr, | /* select_program */ nullptr, | ||||
| # endif | # endif | ||||
| /* get_midi_controller_for_port */ nullptr, | |||||
| dssi_get_midi_controller_for_port, | |||||
| # if DISTRHO_PLUGIN_WANT_MIDI_INPUT | # if DISTRHO_PLUGIN_WANT_MIDI_INPUT | ||||
| dssi_run_synth, | dssi_run_synth, | ||||
| # else | # else | ||||
| @@ -614,11 +633,16 @@ public: | |||||
| const uint32_t hints(plugin.getParameterHints(i)); | const uint32_t hints(plugin.getParameterHints(i)); | ||||
| if (hints & kParameterIsBoolean) | if (hints & kParameterIsBoolean) | ||||
| { | |||||
| portRangeHints[port].HintDescriptor |= LADSPA_HINT_TOGGLED; | 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; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -30,6 +30,10 @@ | |||||
| #include "lv2/lv2_kxstudio_properties.h" | #include "lv2/lv2_kxstudio_properties.h" | ||||
| #include "lv2/lv2_programs.h" | #include "lv2/lv2_programs.h" | ||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| # include "libmodauth.h" | |||||
| #endif | |||||
| #ifdef noexcept | #ifdef noexcept | ||||
| # undef noexcept | # undef noexcept | ||||
| #endif | #endif | ||||
| @@ -58,6 +62,9 @@ class PluginLv2 | |||||
| public: | public: | ||||
| PluginLv2(const double sampleRate, const LV2_URID_Map* const uridMap, const LV2_Worker_Schedule* const worker, const bool usingNominal) | PluginLv2(const double sampleRate, const LV2_URID_Map* const uridMap, const LV2_Worker_Schedule* const worker, const bool usingNominal) | ||||
| : fUsingNominal(usingNominal), | : fUsingNominal(usingNominal), | ||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| fRunCount(0), | |||||
| #endif | |||||
| fPortControls(nullptr), | fPortControls(nullptr), | ||||
| fLastControlValues(nullptr), | fLastControlValues(nullptr), | ||||
| fSampleRate(sampleRate), | fSampleRate(sampleRate), | ||||
| @@ -512,6 +519,12 @@ public: | |||||
| if (fLastControlValues[i] != curValue && ! fPlugin.isParameterOutput(i)) | if (fLastControlValues[i] != curValue && ! fPlugin.isParameterOutput(i)) | ||||
| { | { | ||||
| fLastControlValues[i] = curValue; | fLastControlValues[i] = curValue; | ||||
| if (fPlugin.getParameterDesignation(i) == kParameterDesignationBypass) | |||||
| { | |||||
| curValue = 1.0f - curValue; | |||||
| } | |||||
| fPlugin.setParameterValue(i, curValue); | fPlugin.setParameterValue(i, curValue); | ||||
| } | } | ||||
| } | } | ||||
| @@ -519,12 +532,21 @@ public: | |||||
| // Run plugin | // Run plugin | ||||
| if (sampleCount != 0) | if (sampleCount != 0) | ||||
| { | { | ||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| fRunCount = mod_license_run_begin(fRunCount, sampleCount); | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | ||||
| fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount, fMidiEvents, midiEventCount); | fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount, fMidiEvents, midiEventCount); | ||||
| #else | #else | ||||
| fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount); | fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount); | ||||
| #endif | #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 | #if DISTRHO_PLUGIN_WANT_TIMEPOS | ||||
| // update timePos for next callback | // update timePos for next callback | ||||
| if (d_isNotZero(fLastPositionData.speed)) | if (d_isNotZero(fLastPositionData.speed)) | ||||
| @@ -589,10 +611,14 @@ public: | |||||
| #if DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI | #if DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI | ||||
| const uint32_t capacity = fPortEventsOut->atom.size; | const uint32_t capacity = fPortEventsOut->atom.size; | ||||
| bool needsInit = true; | |||||
| uint32_t size, offset = 0; | uint32_t size, offset = 0; | ||||
| LV2_Atom_Event* aev; | 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 | // TODO - MIDI Output | ||||
| for (uint32_t i=0, count=fPlugin.getStateCount(); i < count; ++i) | for (uint32_t i=0, count=fPlugin.getStateCount(); i < count; ++i) | ||||
| @@ -617,15 +643,6 @@ public: | |||||
| if (sizeof(LV2_Atom_Event) + msgSize > capacity - offset) | if (sizeof(LV2_Atom_Event) + msgSize > capacity - offset) | ||||
| break; | 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 | // reserve msg space | ||||
| char msgBuf[msgSize]; | char msgBuf[msgSize]; | ||||
| std::memset(msgBuf, 0, msgSize); | std::memset(msgBuf, 0, msgSize); | ||||
| @@ -846,6 +863,10 @@ private: | |||||
| PluginExporter fPlugin; | PluginExporter fPlugin; | ||||
| const bool fUsingNominal; // if false use maxBlockLength | const bool fUsingNominal; // if false use maxBlockLength | ||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| uint32_t fRunCount; | |||||
| #endif | |||||
| // LV2 ports | // LV2 ports | ||||
| #if DISTRHO_PLUGIN_NUM_INPUTS > 0 | #if DISTRHO_PLUGIN_NUM_INPUTS > 0 | ||||
| const float* fPortAudioIns[DISTRHO_PLUGIN_NUM_INPUTS]; | const float* fPortAudioIns[DISTRHO_PLUGIN_NUM_INPUTS]; | ||||
| @@ -1034,6 +1055,10 @@ static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, cons | |||||
| } | } | ||||
| #endif | #endif | ||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| mod_check_license(features, DISTRHO_PLUGIN_URI); | |||||
| #endif | |||||
| d_lastBufferSize = 0; | d_lastBufferSize = 0; | ||||
| bool usingNominal = false; | bool usingNominal = false; | ||||
| @@ -1193,7 +1218,11 @@ static const void* lv2_extension_data(const char* uri) | |||||
| return &directaccess; | return &directaccess; | ||||
| #endif | #endif | ||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| return mod_license_interface(uri); | |||||
| #else | |||||
| return nullptr; | return nullptr; | ||||
| #endif | |||||
| } | } | ||||
| #undef instancePtr | #undef instancePtr | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * 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 | * 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 | * 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_kxstudio_properties.h" | ||||
| #include "lv2/lv2_programs.h" | #include "lv2/lv2_programs.h" | ||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| # include "mod-license.h" | |||||
| #endif | |||||
| #include <fstream> | #include <fstream> | ||||
| #include <iostream> | #include <iostream> | ||||
| @@ -224,6 +228,9 @@ void lv2_generate_ttl(const char* const basename) | |||||
| #endif | #endif | ||||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | #if DISTRHO_PLUGIN_WANT_PROGRAMS | ||||
| pluginString += ",\n <" LV2_PROGRAMS__Interface "> "; | pluginString += ",\n <" LV2_PROGRAMS__Interface "> "; | ||||
| #endif | |||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| pluginString += ",\n <" MOD_LICENSE__interface "> "; | |||||
| #endif | #endif | ||||
| pluginString += ";\n\n"; | pluginString += ";\n\n"; | ||||
| @@ -241,6 +248,9 @@ void lv2_generate_ttl(const char* const basename) | |||||
| pluginString += ",\n <" LV2_URID__map "> "; | pluginString += ",\n <" LV2_URID__map "> "; | ||||
| #if DISTRHO_PLUGIN_WANT_STATE | #if DISTRHO_PLUGIN_WANT_STATE | ||||
| pluginString += ",\n <" LV2_WORKER__schedule "> "; | pluginString += ",\n <" LV2_WORKER__schedule "> "; | ||||
| #endif | |||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| pluginString += ",\n <" MOD_LICENSE__feature "> "; | |||||
| #endif | #endif | ||||
| pluginString += ";\n\n"; | pluginString += ";\n\n"; | ||||
| @@ -359,7 +369,7 @@ void lv2_generate_ttl(const char* const basename) | |||||
| pluginString += " lv2:name \"Latency\" ;\n"; | pluginString += " lv2:name \"Latency\" ;\n"; | ||||
| pluginString += " lv2:symbol \"lv2_latency\" ;\n"; | pluginString += " lv2:symbol \"lv2_latency\" ;\n"; | ||||
| pluginString += " lv2:designation 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"; | pluginString += " ] ;\n\n"; | ||||
| ++portIndex; | ++portIndex; | ||||
| #endif | #endif | ||||
| @@ -377,10 +387,34 @@ void lv2_generate_ttl(const char* const basename) | |||||
| pluginString += " a lv2:InputPort, lv2:ControlPort ;\n"; | pluginString += " a lv2:InputPort, lv2:ControlPort ;\n"; | ||||
| pluginString += " lv2:index " + String(portIndex) + " ;\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)); | String symbol(plugin.getParameterSymbol(i)); | ||||
| if (symbol.isEmpty()) | if (symbol.isEmpty()) | ||||
| @@ -390,24 +424,28 @@ void lv2_generate_ttl(const char* const basename) | |||||
| } | } | ||||
| // ranges | // ranges | ||||
| if (! designated) | |||||
| { | { | ||||
| const ParameterRanges& ranges(plugin.getParameterRanges(i)); | const ParameterRanges& ranges(plugin.getParameterRanges(i)); | ||||
| if (plugin.getParameterHints(i) & kParameterIsInteger) | 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:minimum " + String(int(ranges.min)) + " ;\n"; | ||||
| pluginString += " lv2:maximum " + String(int(ranges.max)) + " ;\n"; | pluginString += " lv2:maximum " + String(int(ranges.max)) + " ;\n"; | ||||
| } | } | ||||
| else | 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:minimum " + String(ranges.min) + " ;\n"; | ||||
| pluginString += " lv2:maximum " + String(ranges.max) + " ;\n"; | pluginString += " lv2:maximum " + String(ranges.max) + " ;\n"; | ||||
| } | } | ||||
| } | } | ||||
| // unit | // unit | ||||
| if (! designated) | |||||
| { | { | ||||
| const String& unit(plugin.getParameterUnit(i)); | const String& unit(plugin.getParameterUnit(i)); | ||||
| @@ -453,6 +491,7 @@ void lv2_generate_ttl(const char* const basename) | |||||
| } | } | ||||
| // hints | // hints | ||||
| if (! designated) | |||||
| { | { | ||||
| const uint32_t hints(plugin.getParameterHints(i)); | const uint32_t hints(plugin.getParameterHints(i)); | ||||
| @@ -606,7 +645,18 @@ void lv2_generate_ttl(const char* const basename) | |||||
| plugin.loadProgram(i); | 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 | # if DISTRHO_PLUGIN_WANT_FULL_STATE | ||||
| presetString += " state:state [\n"; | presetString += " state:state [\n"; | ||||
| @@ -629,12 +679,22 @@ void lv2_generate_ttl(const char* const basename) | |||||
| presetString += " ] .\n\n"; | presetString += " ] .\n\n"; | ||||
| # endif | # endif | ||||
| bool firstParameter = true; | |||||
| for (uint32_t j=0; j <numParameters; ++j) | for (uint32_t j=0; j <numParameters; ++j) | ||||
| { | { | ||||
| if (j == 0) | |||||
| if (plugin.isParameterOutput(j)) | |||||
| continue; | |||||
| if (firstParameter) | |||||
| { | |||||
| presetString += " lv2:port [\n"; | presetString += " lv2:port [\n"; | ||||
| firstParameter = false; | |||||
| } | |||||
| else | else | ||||
| { | |||||
| presetString += " [\n"; | presetString += " [\n"; | ||||
| } | |||||
| presetString += " lv2:symbol \"" + plugin.getParameterSymbol(j) + "\" ;\n"; | presetString += " lv2:symbol \"" + plugin.getParameterSymbol(j) + "\" ;\n"; | ||||
| @@ -643,7 +703,7 @@ void lv2_generate_ttl(const char* const basename) | |||||
| else | else | ||||
| presetString += " pset:value " + String(plugin.getParameterValue(j)) + " ;\n"; | presetString += " pset:value " + String(plugin.getParameterValue(j)) + " ;\n"; | ||||
| if (j+1 == numParameters) | |||||
| if (j+1 == numParameters || plugin.isParameterOutput(j+1)) | |||||
| presetString += " ] .\n\n"; | presetString += " ] .\n\n"; | ||||
| else | else | ||||
| presetString += " ] ,\n"; | presetString += " ] ,\n"; | ||||
| @@ -52,6 +52,8 @@ | |||||
| #define effGetProgramNameIndexed 29 | #define effGetProgramNameIndexed 29 | ||||
| #define effGetPlugCategory 35 | #define effGetPlugCategory 35 | ||||
| #define effIdle 53 | #define effIdle 53 | ||||
| #define effEditKeyDown 59 | |||||
| #define effEditKeyUp 60 | |||||
| #define kPlugCategEffect 1 | #define kPlugCategEffect 1 | ||||
| #define kPlugCategSynth 2 | #define kPlugCategSynth 2 | ||||
| #define kVstVersion 2400 | #define kVstVersion 2400 | ||||
| @@ -122,8 +124,20 @@ public: | |||||
| fEffect(effect), | fEffect(effect), | ||||
| fUiHelper(uiHelper), | fUiHelper(uiHelper), | ||||
| fPlugin(plugin), | 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 | # 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: | protected: | ||||
| @@ -231,6 +299,7 @@ private: | |||||
| // Plugin UI | // Plugin UI | ||||
| UIExporter fUI; | UIExporter fUI; | ||||
| bool fShouldCaptureVstKeys; | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Callbacks | // Callbacks | ||||
| @@ -499,6 +568,16 @@ public: | |||||
| if (fVstUI != nullptr) | if (fVstUI != nullptr) | ||||
| fVstUI->idle(); | fVstUI->idle(); | ||||
| break; | 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 | #endif // DISTRHO_PLUGIN_HAS_UI | ||||
| #if DISTRHO_PLUGIN_WANT_STATE | #if DISTRHO_PLUGIN_WANT_STATE | ||||
| @@ -418,6 +418,16 @@ public: | |||||
| return ! glApp.isQuiting(); | 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 | #else | ||||
| void setWindowSize(const uint width, const uint height, const bool updateUI = false) {} | void setWindowSize(const uint width, const uint height, const bool updateUI = false) {} | ||||
| void setWindowTransientWinId(const uintptr_t winId) {} | void setWindowTransientWinId(const uintptr_t winId) {} | ||||
| @@ -23,6 +23,7 @@ | |||||
| #include "lv2/data-access.h" | #include "lv2/data-access.h" | ||||
| #include "lv2/instance-access.h" | #include "lv2/instance-access.h" | ||||
| #include "lv2/options.h" | #include "lv2/options.h" | ||||
| #include "lv2/parameters.h" | |||||
| #include "lv2/ui.h" | #include "lv2/ui.h" | ||||
| #include "lv2/urid.h" | #include "lv2/urid.h" | ||||
| #include "lv2/lv2_kxstudio_properties.h" | #include "lv2/lv2_kxstudio_properties.h" | ||||
| @@ -114,7 +115,9 @@ public: | |||||
| { | { | ||||
| const uint32_t parameterOffset(fUI.getParameterOffset()); | const uint32_t parameterOffset(fUI.getParameterOffset()); | ||||
| DISTRHO_SAFE_ASSERT_RETURN(rindex >= parameterOffset,) | |||||
| if (rindex < parameterOffset) | |||||
| return; | |||||
| DISTRHO_SAFE_ASSERT_RETURN(bufferSize == sizeof(float),) | DISTRHO_SAFE_ASSERT_RETURN(bufferSize == sizeof(float),) | ||||
| const float value(*(const float*)buffer); | const float value(*(const float*)buffer); | ||||
| @@ -173,17 +176,17 @@ public: | |||||
| { | { | ||||
| for (int i=0; options[i].key != 0; ++i) | 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); | fUI.setSampleRate(sampleRate); | ||||
| continue; | continue; | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| d_stderr("Host changed sampleRate but with wrong value type"); | |||||
| d_stderr("Host changed UI sample-rate but with wrong value type"); | |||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| @@ -237,7 +240,7 @@ protected: | |||||
| const size_t msgSize(tmpStr.length()+1); | const size_t msgSize(tmpStr.length()+1); | ||||
| // reserve atom space | // 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]; | char atomBuf[atomSize]; | ||||
| std::memset(atomBuf, 0, atomSize); | std::memset(atomBuf, 0, atomSize); | ||||
| @@ -400,23 +403,23 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* uri, | |||||
| if (options != nullptr) | 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) | for (int i=0; options[i].key != 0; ++i) | ||||
| { | { | ||||
| if (options[i].key == uridSampleRate) | 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 | else | ||||
| d_stderr("Host provides sampleRate but has wrong value type"); | |||||
| d_stderr("Host provides UI sample-rate but has wrong value type"); | |||||
| break; | 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_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; | d_lastUiSampleRate = 44100.0; | ||||