| @@ -255,7 +255,7 @@ jobs: | |||
| - name: Build plugins | |||
| env: | |||
| CFLAGS: -g | |||
| CXXFLAGS: -g | |||
| CXXFLAGS: -g -DDPF_ABORT_ON_ERROR | |||
| LDFLAGS: -static-libgcc -static-libstdc++ | |||
| run: | | |||
| make features | |||
| @@ -33,6 +33,7 @@ endif | |||
| BUILD_C_FLAGS += -I. | |||
| BUILD_CXX_FLAGS += -I. -I$(DPF_PATH)/distrho -I$(DPF_PATH)/dgl | |||
| BUILD_CXX_FLAGS += -Wno-pmf-conversions | |||
| ifeq ($(HAVE_ALSA),true) | |||
| BASE_FLAGS += -DHAVE_ALSA | |||
| @@ -52,7 +52,7 @@ public: | |||
| }; | |||
| explicit ButtonEventHandler(SubWidget* self); | |||
| ~ButtonEventHandler(); | |||
| virtual ~ButtonEventHandler(); | |||
| bool isActive() noexcept; | |||
| void setActive(bool active, bool sendCallback) noexcept; | |||
| @@ -117,7 +117,7 @@ public: | |||
| explicit KnobEventHandler(SubWidget* self); | |||
| explicit KnobEventHandler(SubWidget* self, const KnobEventHandler& other); | |||
| KnobEventHandler& operator=(const KnobEventHandler& other); | |||
| ~KnobEventHandler(); | |||
| virtual ~KnobEventHandler(); | |||
| // returns raw value, is assumed to be scaled if using log | |||
| float getValue() const noexcept; | |||
| @@ -154,6 +154,15 @@ private: | |||
| struct PrivateData; | |||
| PrivateData* const pData; | |||
| /* not for use */ | |||
| #ifdef DISTRHO_PROPER_CPP11_SUPPORT | |||
| KnobEventHandler(KnobEventHandler& other) = delete; | |||
| KnobEventHandler(const KnobEventHandler& other) = delete; | |||
| #else | |||
| KnobEventHandler(KnobEventHandler& other); | |||
| KnobEventHandler(const KnobEventHandler& other); | |||
| #endif | |||
| DISTRHO_LEAK_DETECTOR(KnobEventHandler) | |||
| }; | |||
| @@ -23,6 +23,11 @@ | |||
| #include "TopLevelWidget.hpp" | |||
| #include "StandaloneWindow.hpp" | |||
| #ifdef _MSC_VER | |||
| # pragma warning(push) | |||
| # pragma warning(disable:4661) /* instantiated template classes whose methods are defined elsewhere */ | |||
| #endif | |||
| #ifndef DGL_NO_SHARED_RESOURCES | |||
| # define NANOVG_DEJAVU_SANS_TTF "__dpf_dejavusans_ttf__" | |||
| #endif | |||
| @@ -964,4 +969,8 @@ typedef NanoSubWidget NanoWidget; | |||
| END_NAMESPACE_DGL | |||
| #ifdef _MSC_VER | |||
| # pragma warning(pop) | |||
| #endif | |||
| #endif // DGL_NANO_WIDGET_HPP_INCLUDED | |||
| @@ -114,10 +114,10 @@ Color::Color(const Color& color1, const Color& color2, const float u) noexcept | |||
| interpolate(color2, u); | |||
| } | |||
| Color Color::withAlpha(const float alpha) noexcept | |||
| Color Color::withAlpha(const float alpha2) noexcept | |||
| { | |||
| Color color(*this); | |||
| color.alpha = alpha; | |||
| color.alpha = alpha2; | |||
| return color; | |||
| } | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2021 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 | |||
| @@ -15,8 +15,10 @@ | |||
| */ | |||
| #ifdef _MSC_VER | |||
| // instantiated template classes whose methods are defined elsewhere | |||
| # pragma warning(disable:4661) | |||
| # pragma warning(disable:4661) /* instantiated template classes whose methods are defined elsewhere */ | |||
| #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) | |||
| # pragma GCC diagnostic push | |||
| # pragma GCC diagnostic ignored "-Wconversion" | |||
| #endif | |||
| #include "../Geometry.hpp" | |||
| @@ -678,7 +678,7 @@ void Window::PrivateData::renderToPicture(const char* const filename, | |||
| GLubyte* const pixels = new GLubyte[width * height * 3 * sizeof(GLubyte)]; | |||
| glFlush(); | |||
| glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); | |||
| glReadPixels(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height), GL_RGB, GL_UNSIGNED_BYTE, pixels); | |||
| fprintf(f, "P3\n%d %d\n255\n", width, height); | |||
| for (uint y = 0; y < height; y++) | |||
| @@ -34,7 +34,9 @@ SubWidget::~SubWidget() | |||
| template<typename T> | |||
| bool SubWidget::contains(const T x, const T y) const noexcept | |||
| { | |||
| return Rectangle<double>(0, 0, getWidth()-pData->margin.getX(), getHeight()-pData->margin.getY()).contains(x, y); | |||
| return Rectangle<double>(0, 0, | |||
| static_cast<double>(getWidth()) - pData->margin.getX(), | |||
| static_cast<double>(getHeight()) - pData->margin.getY()).contains(x, y); | |||
| } | |||
| template<typename T> | |||
| @@ -220,10 +220,10 @@ void Window::setSize(uint width, uint height) | |||
| { | |||
| // fix width | |||
| if (reqRatio > ratio) | |||
| width = height * ratio; | |||
| width = static_cast<uint>(height * ratio + 0.5); | |||
| // fix height | |||
| else | |||
| height = width / ratio; | |||
| height = static_cast<uint>(static_cast<double>(width) / ratio + 0.5); | |||
| } | |||
| } | |||
| } | |||
| @@ -542,13 +542,13 @@ bool Window::PrivateData::openFileBrowser(const Window::FileBrowserOptions& opti | |||
| // set start directory in UTF-16 encoding | |||
| std::vector<WCHAR> startDirW; | |||
| startDirW.resize(startDir.length() + 1); | |||
| if (MultiByteToWideChar(CP_UTF8, 0, startDir.buffer(), -1, startDirW.data(), startDirW.size())) | |||
| if (MultiByteToWideChar(CP_UTF8, 0, startDir.buffer(), -1, startDirW.data(), static_cast<int>(startDirW.size()))) | |||
| ofn.lpstrInitialDir = startDirW.data(); | |||
| // set title in UTF-16 encoding | |||
| std::vector<WCHAR> titleW; | |||
| titleW.resize(title.length() + 1); | |||
| if (MultiByteToWideChar(CP_UTF8, 0, title.buffer(), -1, titleW.data(), titleW.size())) | |||
| if (MultiByteToWideChar(CP_UTF8, 0, title.buffer(), -1, titleW.data(), static_cast<int>(titleW.size()))) | |||
| ofn.lpstrTitle = titleW.data(); | |||
| // prepare a buffer to receive the result | |||
| @@ -943,7 +943,7 @@ protected: | |||
| Initialize the parameter @a index.@n | |||
| This function will be called once, shortly after the plugin is created. | |||
| */ | |||
| virtual void initParameter(uint32_t index, Parameter& parameter) = 0; | |||
| virtual void initParameter(uint32_t index, Parameter& parameter); | |||
| /** | |||
| Initialize the port group @a groupId.@n | |||
| @@ -967,7 +967,7 @@ protected: | |||
| This function will be called once, shortly after the plugin is created.@n | |||
| Must be implemented by your plugin class only if DISTRHO_PLUGIN_WANT_STATE is enabled. | |||
| */ | |||
| virtual void initState(uint32_t index, String& stateKey, String& defaultStateValue) = 0; | |||
| virtual void initState(uint32_t index, String& stateKey, String& defaultStateValue); | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATEFILES | |||
| @@ -984,7 +984,7 @@ protected: | |||
| Get the current value of a parameter.@n | |||
| The host may call this function from any context, including realtime processing. | |||
| */ | |||
| virtual float getParameterValue(uint32_t index) const = 0; | |||
| virtual float getParameterValue(uint32_t index) const; | |||
| /** | |||
| Change a parameter value.@n | |||
| @@ -992,7 +992,7 @@ protected: | |||
| When a parameter is marked as automable, you must ensure no non-realtime operations are performed. | |||
| @note This function will only be called for parameter inputs. | |||
| */ | |||
| virtual void setParameterValue(uint32_t index, float value) = 0; | |||
| virtual void setParameterValue(uint32_t index, float value); | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| /** | |||
| @@ -1000,7 +1000,7 @@ protected: | |||
| The host may call this function from any context, including realtime processing.@n | |||
| Must be implemented by your plugin class only if DISTRHO_PLUGIN_WANT_PROGRAMS is enabled. | |||
| */ | |||
| virtual void loadProgram(uint32_t index) = 0; | |||
| virtual void loadProgram(uint32_t index); | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| @@ -1010,7 +1010,7 @@ protected: | |||
| 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; | |||
| virtual String getState(const char* key) const; | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| @@ -1018,7 +1018,7 @@ protected: | |||
| Change an internal state @a key to @a value.@n | |||
| Must be implemented by your plugin class only if DISTRHO_PLUGIN_WANT_STATE is enabled. | |||
| */ | |||
| virtual void setState(const char* key, const char* value) = 0; | |||
| virtual void setState(const char* key, const char* value); | |||
| #endif | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| @@ -193,6 +193,12 @@ private: \ | |||
| # define DISTRHO_OS_SPLIT_STR ":" | |||
| #endif | |||
| /* MSVC warnings */ | |||
| #ifdef _MSC_VER | |||
| # define strdup _strdup | |||
| # pragma warning(disable:4244) /* possible loss of data */ | |||
| #endif | |||
| /* Useful typedefs */ | |||
| typedef unsigned char uchar; | |||
| typedef unsigned short int ushort; | |||
| @@ -44,32 +44,42 @@ Plugin::Plugin(uint32_t parameterCount, uint32_t programCount, uint32_t stateCou | |||
| pData->audioPorts = new AudioPort[DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS]; | |||
| #endif | |||
| #ifdef DPF_ABORT_ON_ERROR | |||
| # define DPF_ABORT abort(); | |||
| #else | |||
| # define DPF_ABORT | |||
| #endif | |||
| if (parameterCount > 0) | |||
| { | |||
| pData->parameterCount = parameterCount; | |||
| pData->parameters = new Parameter[parameterCount]; | |||
| } | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| if (programCount > 0) | |||
| { | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| pData->programCount = programCount; | |||
| pData->programNames = new String[programCount]; | |||
| } | |||
| #else | |||
| DISTRHO_SAFE_ASSERT(programCount == 0); | |||
| d_stderr2("DPF warning: Plugins with programs must define `DISTRHO_PLUGIN_WANT_PROGRAMS` to 1"); | |||
| DPF_ABORT | |||
| #endif | |||
| } | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| if (stateCount > 0) | |||
| { | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| pData->stateCount = stateCount; | |||
| pData->stateKeys = new String[stateCount]; | |||
| pData->stateDefValues = new String[stateCount]; | |||
| } | |||
| #else | |||
| DISTRHO_SAFE_ASSERT(stateCount == 0); | |||
| d_stderr2("DPF warning: Plugins with state must define `DISTRHO_PLUGIN_WANT_STATE` to 1"); | |||
| DPF_ABORT | |||
| #endif | |||
| } | |||
| #undef DPF_ABORT | |||
| } | |||
| Plugin::~Plugin() | |||
| @@ -144,16 +154,48 @@ void Plugin::initAudioPort(bool input, uint32_t index, AudioPort& port) | |||
| } | |||
| } | |||
| void Plugin::initParameter(uint32_t, Parameter&) {} | |||
| void Plugin::initPortGroup(const uint32_t groupId, PortGroup& portGroup) | |||
| { | |||
| fillInPredefinedPortGroupData(groupId, portGroup); | |||
| } | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| void Plugin::initProgramName(uint32_t, String&) {} | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| void Plugin::initState(uint32_t, String&, String&) {} | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATEFILES | |||
| bool Plugin::isStateFile(uint32_t) { return false; } | |||
| #endif | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Init */ | |||
| float Plugin::getParameterValue(uint32_t) const { return 0.0f; } | |||
| void Plugin::setParameterValue(uint32_t, float) {} | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| void Plugin::loadProgram(uint32_t) {} | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| String Plugin::getState(const char*) const { return String(); } | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| void Plugin::setState(const char*, const char*) {} | |||
| #endif | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Callbacks (optional) */ | |||
| void Plugin::bufferSizeChanged(uint32_t) {} | |||
| void Plugin::sampleRateChanged(double) {} | |||
| void Plugin::sampleRateChanged(double) {} | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| @@ -87,6 +87,7 @@ | |||
| #ifndef DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| # define DISTRHO_PLUGIN_WANT_FULL_STATE 0 | |||
| # define DISTRHO_PLUGIN_WANT_FULL_STATE_WAS_NOT_SET | |||
| #endif | |||
| #ifndef DISTRHO_PLUGIN_WANT_TIMEPOS | |||
| @@ -146,8 +147,8 @@ | |||
| // ----------------------------------------------------------------------- | |||
| // Enable full state if plugin exports presets | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS && DISTRHO_PLUGIN_WANT_STATE && ! DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| # warning Plugins with programs and state need to implement full state API too | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS && DISTRHO_PLUGIN_WANT_STATE && defined(DISTRHO_PLUGIN_WANT_FULL_STATE_WAS_NOT_SET) | |||
| # warning Plugins with programs and state should implement full state API too | |||
| # undef DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| # define DISTRHO_PLUGIN_WANT_FULL_STATE 1 | |||
| #endif | |||
| @@ -247,6 +247,85 @@ public: | |||
| DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); | |||
| DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); | |||
| /* Verify that virtual functions are overriden if parameters, programs or states are in use. | |||
| * This does not work on all compilers, but we use it purely as informational check anyway. */ | |||
| #if defined(__GNUC__) && !defined(__clang__) | |||
| # ifdef DPF_ABORT_ON_ERROR | |||
| # define DPF_ABORT abort(); | |||
| # else | |||
| # define DPF_ABORT | |||
| # endif | |||
| if (fData->parameterCount != 0) | |||
| { | |||
| if ((void*)(fPlugin->*(&Plugin::initParameter)) == (void*)&Plugin::initParameter) | |||
| { | |||
| d_stderr2("DPF warning: Plugins with parameters must implement `initParameter`"); | |||
| DPF_ABORT | |||
| } | |||
| if ((void*)(fPlugin->*(&Plugin::getParameterValue)) == (void*)&Plugin::getParameterValue) | |||
| { | |||
| d_stderr2("DPF warning: Plugins with parameters must implement `getParameterValue`"); | |||
| DPF_ABORT | |||
| } | |||
| if ((void*)(fPlugin->*(&Plugin::setParameterValue)) == (void*)&Plugin::setParameterValue) | |||
| { | |||
| d_stderr2("DPF warning: Plugins with parameters must implement `setParameterValue`"); | |||
| DPF_ABORT | |||
| } | |||
| } | |||
| # if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| if (fData->programCount != 0) | |||
| { | |||
| if ((void*)(fPlugin->*(&Plugin::initProgramName)) == (void*)&Plugin::initProgramName) | |||
| { | |||
| d_stderr2("DPF warning: Plugins with programs must implement `initProgramName`"); | |||
| DPF_ABORT | |||
| } | |||
| if ((void*)(fPlugin->*(&Plugin::loadProgram)) == (void*)&Plugin::loadProgram) | |||
| { | |||
| d_stderr2("DPF warning: Plugins with programs must implement `loadProgram`"); | |||
| DPF_ABORT | |||
| } | |||
| } | |||
| # endif | |||
| # if DISTRHO_PLUGIN_WANT_STATE | |||
| if (fData->stateCount != 0) | |||
| { | |||
| if ((void*)(fPlugin->*(&Plugin::initState)) == (void*)&Plugin::initState) | |||
| { | |||
| d_stderr2("DPF warning: Plugins with state must implement `initState`"); | |||
| DPF_ABORT | |||
| } | |||
| if ((void*)(fPlugin->*(&Plugin::setState)) == (void*)&Plugin::setState) | |||
| { | |||
| d_stderr2("DPF warning: Plugins with state must implement `setState`"); | |||
| DPF_ABORT | |||
| } | |||
| } | |||
| # endif | |||
| # if DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| if (fData->stateCount != 0) | |||
| { | |||
| if ((void*)(fPlugin->*(&Plugin::getState)) == (void*)&Plugin::getState) | |||
| { | |||
| d_stderr2("DPF warning: Plugins with full state must implement `getState`"); | |||
| DPF_ABORT | |||
| } | |||
| } | |||
| else | |||
| { | |||
| d_stderr2("DPF warning: Plugins with full state must have at least 1 state"); | |||
| DPF_ABORT | |||
| } | |||
| # endif | |||
| # undef DPF_ABORT | |||
| #endif | |||
| #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0 | |||
| { | |||
| uint32_t j=0; | |||
| @@ -276,7 +355,7 @@ public: | |||
| portGroupIndices.erase(kPortGroupNone); | |||
| if (const size_t portGroupSize = portGroupIndices.size()) | |||
| if (const uint32_t portGroupSize = static_cast<uint32_t>(portGroupIndices.size())) | |||
| { | |||
| fData->portGroups = new PortGroupWithId[portGroupSize]; | |||
| fData->portGroupCount = portGroupSize; | |||
| @@ -469,7 +469,7 @@ protected: | |||
| MidiEvent& midiEvent(midiEvents[midiEventCount++]); | |||
| midiEvent.frame = jevent.time; | |||
| midiEvent.size = jevent.size; | |||
| midiEvent.size = static_cast<uint32_t>(jevent.size); | |||
| if (midiEvent.size > MidiEvent::kDataSize) | |||
| midiEvent.dataExt = jevent.buffer; | |||
| @@ -708,7 +708,7 @@ public: | |||
| const String& value(cit->second); | |||
| // set msg size (key + value + separator + 2x null terminator) | |||
| const size_t msgSize = key.length()+value.length()+3; | |||
| const uint32_t msgSize = static_cast<uint32_t>(key.length()+value.length())+3U; | |||
| if (sizeof(LV2_Atom_Event) + msgSize > capacity - fEventsOutData.offset) | |||
| { | |||
| @@ -285,11 +285,13 @@ protected: | |||
| tmpStr[std::strlen(key)] = '\0'; | |||
| // set msg size (key + separator + value + null terminator) | |||
| const size_t msgSize = tmpStr.length() + 1U; | |||
| const uint32_t msgSize = static_cast<uint32_t>(tmpStr.length()) + 1U; | |||
| // reserve atom space | |||
| const size_t atomSize = sizeof(LV2_Atom) + msgSize; | |||
| const uint32_t atomSize = sizeof(LV2_Atom) + msgSize; | |||
| char* const atomBuf = (char*)malloc(atomSize); | |||
| DISTRHO_SAFE_ASSERT_RETURN(atomBuf != nullptr,); | |||
| std::memset(atomBuf, 0, atomSize); | |||
| // set atom info | |||
| @@ -29,13 +29,10 @@ BUILD_CXX_FLAGS += -Wno-unused-parameter | |||
| # -------------------------------------------------------------- | |||
| # Enable all possible plugin types | |||
| ifeq ($(HAVE_JACK),true) | |||
| TARGETS += jack | |||
| endif | |||
| TARGETS += ladspa | |||
| TARGETS += lv2_dsp | |||
| TARGETS += vst | |||
| TARGETS += vst2 | |||
| all: $(TARGETS) | |||
| @@ -221,6 +221,7 @@ void genlib_data_release(t_genlib_data *b) { | |||
| genlib_sysmem_freeptr(self->info.data); | |||
| self->info.data = 0; | |||
| } | |||
| genlib_sysmem_freeptr(self); | |||
| } | |||
| long genlib_data_getcursor(t_genlib_data *b) { | |||
| @@ -29,13 +29,10 @@ BUILD_CXX_FLAGS += -Wno-unused-parameter | |||
| # -------------------------------------------------------------- | |||
| # Enable all possible plugin types | |||
| ifeq ($(HAVE_JACK),true) | |||
| TARGETS += jack | |||
| endif | |||
| TARGETS += ladspa | |||
| TARGETS += lv2_dsp | |||
| TARGETS += vst | |||
| TARGETS += vst2 | |||
| all: $(TARGETS) | |||
| @@ -29,13 +29,10 @@ BUILD_CXX_FLAGS += -Wno-unused-parameter | |||
| # -------------------------------------------------------------- | |||
| # Enable all possible plugin types | |||
| ifeq ($(HAVE_JACK),true) | |||
| TARGETS += jack | |||
| endif | |||
| TARGETS += ladspa | |||
| TARGETS += lv2_dsp | |||
| TARGETS += vst | |||
| TARGETS += vst2 | |||
| all: $(TARGETS) | |||
| @@ -29,13 +29,10 @@ BUILD_CXX_FLAGS += -Wno-unused-parameter | |||
| # -------------------------------------------------------------- | |||
| # Enable all possible plugin types | |||
| ifeq ($(HAVE_JACK),true) | |||
| TARGETS += jack | |||
| endif | |||
| TARGETS += ladspa | |||
| TARGETS += lv2_dsp | |||
| TARGETS += vst | |||
| TARGETS += vst2 | |||
| all: $(TARGETS) | |||