| @@ -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/ | |||
| @@ -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. | |||
| @@ -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 | |||
| */ | |||
| @@ -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) | |||
| }; | |||
| @@ -68,7 +68,9 @@ Image::~Image() | |||
| { | |||
| if (fTextureId != 0) | |||
| { | |||
| #ifndef DISTRHO_OS_MAC // FIXME | |||
| glDeleteTextures(1, &fTextureId); | |||
| #endif | |||
| fTextureId = 0; | |||
| } | |||
| } | |||
| @@ -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 | |||
| @@ -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() | |||
| @@ -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; | |||
| @@ -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; | |||
| } | |||
| @@ -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,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 | |||
| @@ -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 | |||
| @@ -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); | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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); | |||
| @@ -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 | |||
| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| @@ -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 | |||
| @@ -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"; | |||
| @@ -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 | |||
| @@ -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) {} | |||
| @@ -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; | |||