Browse Source

Update DPF and plugins, passing validation

Signed-off-by: falkTX <falktx@falktx.com>
tags/v1.5
falkTX 3 years ago
parent
commit
0d54329998
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
53 changed files with 885 additions and 104 deletions
  1. +5
    -10
      dpf/Makefile.base.mk
  2. +25
    -8
      dpf/Makefile.plugins.mk
  3. +27
    -0
      dpf/cmake/DPF-plugin.cmake
  4. +16
    -2
      dpf/dgl/NanoVG.hpp
  5. +7
    -0
      dpf/dgl/Window.hpp
  6. +7
    -0
      dpf/dgl/src/Cairo.cpp
  7. +44
    -2
      dpf/dgl/src/NanoVG.cpp
  8. +30
    -0
      dpf/dgl/src/OpenGL.cpp
  9. +7
    -0
      dpf/dgl/src/Vulkan.cpp
  10. +5
    -0
      dpf/dgl/src/Window.cpp
  11. +13
    -0
      dpf/dgl/src/WindowPrivateData.cpp
  12. +5
    -0
      dpf/dgl/src/WindowPrivateData.hpp
  13. +6
    -1
      dpf/dgl/src/nanovg/nanovg.c
  14. +12
    -5
      dpf/dgl/src/nanovg/nanovg.h
  15. +68
    -10
      dpf/dgl/src/nanovg/nanovg_gl.h
  16. +1
    -1
      dpf/distrho/DistrhoInfo.hpp
  17. +1
    -1
      dpf/distrho/DistrhoPluginMain.cpp
  18. +4
    -4
      dpf/distrho/DistrhoPluginUtils.hpp
  19. +30
    -0
      dpf/distrho/extra/String.hpp
  20. +5
    -6
      dpf/distrho/src/DistrhoPluginChecks.h
  21. +194
    -24
      dpf/distrho/src/DistrhoPluginLV2export.cpp
  22. +17
    -1
      dpf/distrho/src/DistrhoPluginVST2.cpp
  23. +7
    -2
      dpf/tests/Makefile
  24. +229
    -0
      dpf/tests/NanoImage.cpp
  25. +4
    -4
      dpf/utils/lv2-ttl-generator/GNUmakefile
  26. +3
    -0
      dpf/utils/symbols/dssi.def
  27. +2
    -0
      dpf/utils/symbols/dssi.exp
  28. +4
    -0
      dpf/utils/symbols/dssi.version
  29. +2
    -0
      dpf/utils/symbols/ladspa.def
  30. +1
    -0
      dpf/utils/symbols/ladspa.exp
  31. +4
    -0
      dpf/utils/symbols/ladspa.version
  32. +3
    -0
      dpf/utils/symbols/lv2-dsp.def
  33. +2
    -0
      dpf/utils/symbols/lv2-dsp.exp
  34. +4
    -0
      dpf/utils/symbols/lv2-dsp.version
  35. +2
    -0
      dpf/utils/symbols/lv2-ui.def
  36. +1
    -0
      dpf/utils/symbols/lv2-ui.exp
  37. +4
    -0
      dpf/utils/symbols/lv2-ui.version
  38. +4
    -0
      dpf/utils/symbols/lv2.def
  39. +3
    -0
      dpf/utils/symbols/lv2.exp
  40. +4
    -0
      dpf/utils/symbols/lv2.version
  41. +3
    -0
      dpf/utils/symbols/vst2.def
  42. +1
    -0
      dpf/utils/symbols/vst2.exp
  43. +4
    -0
      dpf/utils/symbols/vst2.version
  44. +4
    -0
      dpf/utils/symbols/vst3.def
  45. +3
    -0
      dpf/utils/symbols/vst3.exp
  46. +4
    -0
      dpf/utils/symbols/vst3.version
  47. +41
    -0
      dpf/utils/valgrind-dpf.supp
  48. +0
    -18
      plugins/Nekobi/DistrhoPluginNekobi.cpp
  49. +0
    -2
      plugins/Nekobi/DistrhoPluginNekobi.hpp
  50. +3
    -0
      plugins/ProM/DistrhoUIProM.cpp
  51. +2
    -2
      plugins/glBars/DistrhoPluginGLBars.cpp
  52. +7
    -1
      plugins/glBars/DistrhoUIGLBars.cpp
  53. +1
    -0
      plugins/glBars/DistrhoUIGLBars.hpp

+ 5
- 10
dpf/Makefile.base.mk View File

@@ -29,22 +29,17 @@ ifneq ($(WINDOWS),true)


ifneq (,$(findstring bsd,$(TARGET_MACHINE))) ifneq (,$(findstring bsd,$(TARGET_MACHINE)))
BSD=true BSD=true
endif
ifneq (,$(findstring haiku,$(TARGET_MACHINE)))
else ifneq (,$(findstring haiku,$(TARGET_MACHINE)))
HAIKU=true HAIKU=true
endif
ifneq (,$(findstring linux,$(TARGET_MACHINE)))
else ifneq (,$(findstring linux,$(TARGET_MACHINE)))
LINUX=true LINUX=true
else ifneq (,$(findstring gnu,$(TARGET_MACHINE))) else ifneq (,$(findstring gnu,$(TARGET_MACHINE)))
HURD=true HURD=true
endif
ifneq (,$(findstring apple,$(TARGET_MACHINE)))
else ifneq (,$(findstring apple,$(TARGET_MACHINE)))
MACOS=true MACOS=true
endif
ifneq (,$(findstring mingw,$(TARGET_MACHINE)))
else ifneq (,$(findstring mingw,$(TARGET_MACHINE)))
WINDOWS=true WINDOWS=true
endif
ifneq (,$(findstring windows,$(TARGET_MACHINE)))
else ifneq (,$(findstring windows,$(TARGET_MACHINE)))
WINDOWS=true WINDOWS=true
endif endif




+ 25
- 8
dpf/Makefile.plugins.mk View File

@@ -112,12 +112,29 @@ endif
# Set plugin symbols to export # Set plugin symbols to export


ifeq ($(MACOS),true) ifeq ($(MACOS),true)
SYMBOLS_LADSPA = -Wl,-exported_symbol,_ladspa_descriptor
SYMBOLS_DSSI = -Wl,-exported_symbol,_ladspa_descriptor -Wl,-exported_symbol,_dssi_descriptor
SYMBOLS_LV2 = -Wl,-exported_symbol,_lv2_descriptor -Wl,-exported_symbol,_lv2_generate_ttl
SYMBOLS_LV2UI = -Wl,-exported_symbol,_lv2ui_descriptor
SYMBOLS_VST2 = -Wl,-exported_symbol,_VSTPluginMain
SYMBOLS_VST3 = -Wl,-exported_symbol,_GetPluginFactory -Wl,-exported_symbol,_bundleEntry -Wl,-exported_symbol,_bundleExit
SYMBOLS_LADSPA = -Wl,-exported_symbols_list,$(DPF_PATH)/utils/symbols/ladspa.exp
SYMBOLS_DSSI = -Wl,-exported_symbols_list,$(DPF_PATH)/utils/symbols/dssi.exp
SYMBOLS_LV2DSP = -Wl,-exported_symbols_list,$(DPF_PATH)/utils/symbols/lv2-dsp.exp
SYMBOLS_LV2UI = -Wl,-exported_symbols_list,$(DPF_PATH)/utils/symbols/lv2-ui.exp
SYMBOLS_LV2 = -Wl,-exported_symbols_list,$(DPF_PATH)/utils/symbols/lv2.exp
SYMBOLS_VST2 = -Wl,-exported_symbols_list,$(DPF_PATH)/utils/symbols/vst2.exp
SYMBOLS_VST3 = -Wl,-exported_symbols_list,$(DPF_PATH)/utils/symbols/vst3.exp
else ifeq ($(WINDOWS),true)
SYMBOLS_LADSPA = $(DPF_PATH)/utils/symbols/ladspa.def
SYMBOLS_DSSI = $(DPF_PATH)/utils/symbols/dssi.def
SYMBOLS_LV2DSP = $(DPF_PATH)/utils/symbols/lv2-dsp.def
SYMBOLS_LV2UI = $(DPF_PATH)/utils/symbols/lv2-ui.def
SYMBOLS_LV2 = $(DPF_PATH)/utils/symbols/lv2.def
SYMBOLS_VST2 = $(DPF_PATH)/utils/symbols/vst2.def
SYMBOLS_VST3 = $(DPF_PATH)/utils/symbols/vst3.def
else
SYMBOLS_LADSPA = -Wl,--version-script=$(DPF_PATH)/utils/symbols/ladspa.version
SYMBOLS_DSSI = -Wl,--version-script=$(DPF_PATH)/utils/symbols/dssi.version
SYMBOLS_LV2DSP = -Wl,--version-script=$(DPF_PATH)/utils/symbols/lv2-dsp.version
SYMBOLS_LV2UI = -Wl,--version-script=$(DPF_PATH)/utils/symbols/lv2-ui.version
SYMBOLS_LV2 = -Wl,--version-script=$(DPF_PATH)/utils/symbols/lv2.version
SYMBOLS_VST2 = -Wl,--version-script=$(DPF_PATH)/utils/symbols/vst2.version
SYMBOLS_VST3 = -Wl,--version-script=$(DPF_PATH)/utils/symbols/vst3.version
endif endif


# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------
@@ -337,12 +354,12 @@ $(lv2): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.o
endif endif
-@mkdir -p $(shell dirname $@) -@mkdir -p $(shell dirname $@)
@echo "Creating LV2 plugin for $(NAME)" @echo "Creating LV2 plugin for $(NAME)"
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) $(SYMBOLS_LV2) $(SYMBOLS_LV2UI) -o $@
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) $(SYMBOLS_LV2) -o $@


$(lv2_dsp): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.o $(lv2_dsp): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.o
-@mkdir -p $(shell dirname $@) -@mkdir -p $(shell dirname $@)
@echo "Creating LV2 plugin library for $(NAME)" @echo "Creating LV2 plugin library for $(NAME)"
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) $(SYMBOLS_LV2) -o $@
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) $(SYMBOLS_LV2DSP) -o $@


$(lv2_ui): $(OBJS_UI) $(BUILD_DIR)/DistrhoUIMain_LV2.cpp.o $(DGL_LIB) $(lv2_ui): $(OBJS_UI) $(BUILD_DIR)/DistrhoUIMain_LV2.cpp.o $(DGL_LIB)
-@mkdir -p $(shell dirname $@) -@mkdir -p $(shell dirname $@)


+ 27
- 0
dpf/cmake/DPF-plugin.cmake View File

@@ -206,6 +206,7 @@ function(dpf__build_ladspa NAME)


dpf__add_module("${NAME}-ladspa" ${_no_srcs}) dpf__add_module("${NAME}-ladspa" ${_no_srcs})
dpf__add_plugin_main("${NAME}-ladspa" "ladspa") dpf__add_plugin_main("${NAME}-ladspa" "ladspa")
dpf__set_module_export_list("${NAME}-ladspa" "ladspa")
target_link_libraries("${NAME}-ladspa" PRIVATE "${NAME}-dsp") target_link_libraries("${NAME}-ladspa" PRIVATE "${NAME}-dsp")
set_target_properties("${NAME}-ladspa" PROPERTIES set_target_properties("${NAME}-ladspa" PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>"
@@ -234,6 +235,7 @@ function(dpf__build_dssi NAME DGL_LIBRARY)


dpf__add_module("${NAME}-dssi" ${_no_srcs}) dpf__add_module("${NAME}-dssi" ${_no_srcs})
dpf__add_plugin_main("${NAME}-dssi" "dssi") dpf__add_plugin_main("${NAME}-dssi" "dssi")
dpf__set_module_export_list("${NAME}-dssi" "dssi")
target_link_libraries("${NAME}-dssi" PRIVATE "${NAME}-dsp") target_link_libraries("${NAME}-dssi" PRIVATE "${NAME}-dsp")
set_target_properties("${NAME}-dssi" PROPERTIES set_target_properties("${NAME}-dssi" PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>"
@@ -264,6 +266,11 @@ function(dpf__build_lv2 NAME DGL_LIBRARY MONOLITHIC)


dpf__add_module("${NAME}-lv2" ${_no_srcs}) dpf__add_module("${NAME}-lv2" ${_no_srcs})
dpf__add_plugin_main("${NAME}-lv2" "lv2") dpf__add_plugin_main("${NAME}-lv2" "lv2")
if(DGL_LIBRARY AND MONOLITHIC)
dpf__set_module_export_list("${NAME}-lv2" "lv2")
else()
dpf__set_module_export_list("${NAME}-lv2" "lv2-dsp")
endif()
target_link_libraries("${NAME}-lv2" PRIVATE "${NAME}-dsp") target_link_libraries("${NAME}-lv2" PRIVATE "${NAME}-dsp")
set_target_properties("${NAME}-lv2" PROPERTIES set_target_properties("${NAME}-lv2" PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2/$<0:>" LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2/$<0:>"
@@ -280,6 +287,7 @@ function(dpf__build_lv2 NAME DGL_LIBRARY MONOLITHIC)
else() else()
dpf__add_module("${NAME}-lv2-ui" ${_no_srcs}) dpf__add_module("${NAME}-lv2-ui" ${_no_srcs})
dpf__add_ui_main("${NAME}-lv2-ui" "lv2" "${DGL_LIBRARY}") dpf__add_ui_main("${NAME}-lv2-ui" "lv2" "${DGL_LIBRARY}")
dpf__set_module_export_list("${NAME}-lv2-ui" "lv2-ui")
target_link_libraries("${NAME}-lv2-ui" PRIVATE "${NAME}-ui") target_link_libraries("${NAME}-lv2-ui" PRIVATE "${NAME}-ui")
set_target_properties("${NAME}-lv2-ui" PROPERTIES set_target_properties("${NAME}-lv2-ui" PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2/$<0:>" LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2/$<0:>"
@@ -311,6 +319,7 @@ function(dpf__build_vst2 NAME DGL_LIBRARY)
dpf__add_module("${NAME}-vst2" ${_no_srcs}) dpf__add_module("${NAME}-vst2" ${_no_srcs})
dpf__add_plugin_main("${NAME}-vst2" "vst2") dpf__add_plugin_main("${NAME}-vst2" "vst2")
dpf__add_ui_main("${NAME}-vst2" "vst2" "${DGL_LIBRARY}") dpf__add_ui_main("${NAME}-vst2" "vst2" "${DGL_LIBRARY}")
dpf__set_module_export_list("${NAME}-vst2" "vst2")
target_link_libraries("${NAME}-vst2" PRIVATE "${NAME}-dsp" "${NAME}-ui") target_link_libraries("${NAME}-vst2" PRIVATE "${NAME}-dsp" "${NAME}-ui")
set_target_properties("${NAME}-vst2" PROPERTIES set_target_properties("${NAME}-vst2" PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>"
@@ -566,6 +575,24 @@ function(dpf__add_static_library NAME)
dpf__set_target_defaults("${NAME}") dpf__set_target_defaults("${NAME}")
endfunction() endfunction()


# dpf__set_module_export_list
# ------------------------------------------------------------------------------
#
# Applies a list of exported symbols to the module target.
#
function(dpf__set_module_export_list NAME EXPORTS)
if(WIN32)
target_sources("${NAME}" PRIVATE "${DPF_ROOT_DIR}/utils/symbols/${EXPORTS}.def")
elseif(APPLE)
set_property(TARGET "${NAME}" APPEND PROPERTY LINK_OPTIONS
"-Xlinker" "-exported_symbols_list"
"-Xlinker" "${DPF_ROOT_DIR}/utils/symbols/${EXPORTS}.exp")
else()
set_property(TARGET "${NAME}" APPEND PROPERTY LINK_OPTIONS
"-Xlinker" "--version-script=${DPF_ROOT_DIR}/utils/symbols/${EXPORTS}.version")
endif()
endfunction()

# dpf__set_target_defaults # dpf__set_target_defaults
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# #


+ 16
- 2
dpf/dgl/NanoVG.hpp View File

@@ -582,12 +582,26 @@ public:
NanoImage::Handle createImageFromMemory(uchar* data, uint dataSize, int imageFlags); NanoImage::Handle createImageFromMemory(uchar* data, uint dataSize, int imageFlags);


/** /**
Creates image from specified image data.
Creates image from specified raw format image data.
*/
NanoImage::Handle createImageFromRawMemory(uint w, uint h, const uchar* data,
ImageFlags imageFlags, ImageFormat format);

/**
Creates image from specified raw format image data.
Overloaded function for convenience.
@see ImageFlags
*/
NanoImage::Handle createImageFromRawMemory(uint w, uint h, const uchar* data,
int imageFlags, ImageFormat format);

/**
Creates image from specified RGBA image data.
*/ */
NanoImage::Handle createImageFromRGBA(uint w, uint h, const uchar* data, ImageFlags imageFlags); NanoImage::Handle createImageFromRGBA(uint w, uint h, const uchar* data, ImageFlags imageFlags);


/** /**
Creates image from specified image data.
Creates image from specified RGBA image data.
Overloaded function for convenience. Overloaded function for convenience.
@see ImageFlags @see ImageFlags
*/ */


+ 7
- 0
dpf/dgl/Window.hpp View File

@@ -382,6 +382,13 @@ public:
*/ */
void repaint(const Rectangle<uint>& rect) noexcept; void repaint(const Rectangle<uint>& rect) noexcept;


/**
Render this window's content into a picture file, specified by @a filename.
Window must be visible and on screen.
Written picture format is PPM.
*/
void renderToPicture(const char* filename);

/** /**
Run this window as a modal, blocking input events from the parent. Run this window as a modal, blocking input events from the parent.
Only valid for windows that have been created with another window as parent (as passed in the constructor). Only valid for windows that have been created with another window as parent (as passed in the constructor).


+ 7
- 0
dpf/dgl/src/Cairo.cpp View File

@@ -808,6 +808,13 @@ void TopLevelWidget::PrivateData::display()


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


void Window::PrivateData::renderToPicture(const char*, const GraphicsContext&, uint, uint)
{
notImplemented("Window::PrivateData::renderToPicture");
}

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

const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept
{ {
GraphicsContext& context((GraphicsContext&)graphicsContext); GraphicsContext& context((GraphicsContext&)graphicsContext);


+ 44
- 2
dpf/dgl/src/NanoVG.cpp View File

@@ -215,6 +215,7 @@ NanoImage& NanoImage::operator=(const Handle& handle)


fHandle.context = handle.context; fHandle.context = handle.context;
fHandle.imageId = handle.imageId; fHandle.imageId = handle.imageId;
_updateSize();


return *this; return *this;
} }
@@ -631,6 +632,45 @@ NanoImage::Handle NanoVG::createImageFromMemory(uchar* data, uint dataSize, int
return NanoImage::Handle(fContext, nvgCreateImageMem(fContext, imageFlags, data,static_cast<int>(dataSize))); return NanoImage::Handle(fContext, nvgCreateImageMem(fContext, imageFlags, data,static_cast<int>(dataSize)));
} }


NanoImage::Handle NanoVG::createImageFromRawMemory(uint w, uint h, const uchar* data,
ImageFlags imageFlags, ImageFormat format)
{
return createImageFromRawMemory(w, h, data, static_cast<int>(imageFlags), format);
}

NanoImage::Handle NanoVG::createImageFromRawMemory(uint w, uint h, const uchar* data,
int imageFlags, ImageFormat format)
{
if (fContext == nullptr) return NanoImage::Handle();
DISTRHO_SAFE_ASSERT_RETURN(data != nullptr, NanoImage::Handle());

NVGtexture nvgformat;
switch (format)
{
case kImageFormatGrayscale:
nvgformat = NVG_TEXTURE_ALPHA;
break;
case kImageFormatBGR:
nvgformat = NVG_TEXTURE_BGR;
break;
case kImageFormatBGRA:
nvgformat = NVG_TEXTURE_BGRA;
break;
case kImageFormatRGB:
nvgformat = NVG_TEXTURE_RGB;
break;
case kImageFormatRGBA:
nvgformat = NVG_TEXTURE_RGBA;
break;
default:
return NanoImage::Handle();
}

return NanoImage::Handle(fContext, nvgCreateImageRaw(fContext,
static_cast<int>(w),
static_cast<int>(h), imageFlags, nvgformat, data));
}

NanoImage::Handle NanoVG::createImageFromRGBA(uint w, uint h, const uchar* data, ImageFlags imageFlags) NanoImage::Handle NanoVG::createImageFromRGBA(uint w, uint h, const uchar* data, ImageFlags imageFlags)
{ {
return createImageFromRGBA(w, h, data, static_cast<int>(imageFlags)); return createImageFromRGBA(w, h, data, static_cast<int>(imageFlags));
@@ -646,12 +686,14 @@ NanoImage::Handle NanoVG::createImageFromRGBA(uint w, uint h, const uchar* data,
static_cast<int>(h), imageFlags, data)); static_cast<int>(h), imageFlags, data));
} }


NanoImage::Handle NanoVG::createImageFromTextureHandle(GLuint textureId, uint w, uint h, ImageFlags imageFlags, bool deleteTexture)
NanoImage::Handle NanoVG::createImageFromTextureHandle(GLuint textureId, uint w, uint h,
ImageFlags imageFlags, bool deleteTexture)
{ {
return createImageFromTextureHandle(textureId, w, h, static_cast<int>(imageFlags), deleteTexture); return createImageFromTextureHandle(textureId, w, h, static_cast<int>(imageFlags), deleteTexture);
} }


NanoImage::Handle NanoVG::createImageFromTextureHandle(GLuint textureId, uint w, uint h, int imageFlags, bool deleteTexture)
NanoImage::Handle NanoVG::createImageFromTextureHandle(GLuint textureId, uint w, uint h,
int imageFlags, bool deleteTexture)
{ {
if (fContext == nullptr) return NanoImage::Handle(); if (fContext == nullptr) return NanoImage::Handle();
DISTRHO_SAFE_ASSERT_RETURN(textureId != 0, NanoImage::Handle()); DISTRHO_SAFE_ASSERT_RETURN(textureId != 0, NanoImage::Handle());


+ 30
- 0
dpf/dgl/src/OpenGL.cpp View File

@@ -667,6 +667,36 @@ void TopLevelWidget::PrivateData::display()


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


void Window::PrivateData::renderToPicture(const char* const filename,
const GraphicsContext&,
const uint width,
const uint height)
{
FILE* const f = fopen(filename, "w");
DISTRHO_SAFE_ASSERT_RETURN(f != nullptr,);

GLubyte* const pixels = new GLubyte[width * height * 3 * sizeof(GLubyte)];

glFlush();
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);

fprintf(f, "P3\n%d %d\n255\n", width, height);
for (uint y = 0; y < height; y++)
{
for (uint i, x = 0; x < width; x++)
{
i = 3 * ((height - y - 1) * width + x);
fprintf(f, "%3d %3d %3d ", pixels[i], pixels[i+1], pixels[i+2]);
}
fprintf(f, "\n");
}

delete[] pixels;
fclose(f);
}

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

const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept
{ {
return (const GraphicsContext&)graphicsContext; return (const GraphicsContext&)graphicsContext;


+ 7
- 0
dpf/dgl/src/Vulkan.cpp View File

@@ -231,6 +231,13 @@ void TopLevelWidget::PrivateData::display()


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


void Window::PrivateData::renderToPicture(const char*, const GraphicsContext&, uint, uint)
{
notImplemented("Window::PrivateData::renderToPicture");
}

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

const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept
{ {
return (const GraphicsContext&)graphicsContext; return (const GraphicsContext&)graphicsContext;


+ 5
- 0
dpf/dgl/src/Window.cpp View File

@@ -336,6 +336,11 @@ void Window::repaint(const Rectangle<uint>& rect) noexcept
puglPostRedisplayRect(pData->view, prect); puglPostRedisplayRect(pData->view, prect);
} }


void Window::renderToPicture(const char* const filename)
{
pData->filenameToRenderInto = strdup(filename);
}

void Window::runAsModal(bool blockWait) void Window::runAsModal(bool blockWait)
{ {
pData->runAsModal(blockWait); pData->runAsModal(blockWait);


+ 13
- 0
dpf/dgl/src/WindowPrivateData.cpp View File

@@ -95,6 +95,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s)
minHeight(0), minHeight(0),
keepAspectRatio(false), keepAspectRatio(false),
ignoreIdleCallbacks(false), ignoreIdleCallbacks(false),
filenameToRenderInto(nullptr),
#ifdef DISTRHO_OS_WINDOWS #ifdef DISTRHO_OS_WINDOWS
win32SelectedFile(nullptr), win32SelectedFile(nullptr),
#endif #endif
@@ -120,6 +121,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c
minHeight(0), minHeight(0),
keepAspectRatio(false), keepAspectRatio(false),
ignoreIdleCallbacks(false), ignoreIdleCallbacks(false),
filenameToRenderInto(nullptr),
#ifdef DISTRHO_OS_WINDOWS #ifdef DISTRHO_OS_WINDOWS
win32SelectedFile(nullptr), win32SelectedFile(nullptr),
#endif #endif
@@ -149,6 +151,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
minHeight(0), minHeight(0),
keepAspectRatio(false), keepAspectRatio(false),
ignoreIdleCallbacks(false), ignoreIdleCallbacks(false),
filenameToRenderInto(nullptr),
#ifdef DISTRHO_OS_WINDOWS #ifdef DISTRHO_OS_WINDOWS
win32SelectedFile(nullptr), win32SelectedFile(nullptr),
#endif #endif
@@ -180,6 +183,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
minHeight(0), minHeight(0),
keepAspectRatio(false), keepAspectRatio(false),
ignoreIdleCallbacks(false), ignoreIdleCallbacks(false),
filenameToRenderInto(nullptr),
#ifdef DISTRHO_OS_WINDOWS #ifdef DISTRHO_OS_WINDOWS
win32SelectedFile(nullptr), win32SelectedFile(nullptr),
#endif #endif
@@ -195,6 +199,7 @@ Window::PrivateData::~PrivateData()
{ {
appData->idleCallbacks.remove(this); appData->idleCallbacks.remove(this);
appData->windows.remove(self); appData->windows.remove(self);
std::free(filenameToRenderInto);


if (view == nullptr) if (view == nullptr)
return; return;
@@ -743,6 +748,14 @@ void Window::PrivateData::onPuglExpose()
if (widget->isVisible()) if (widget->isVisible())
widget->pData->display(); widget->pData->display();
} }

if (char* const filename = filenameToRenderInto)
{
const PuglRect rect = puglGetFrame(view);
filenameToRenderInto = nullptr;
renderToPicture(filename, getGraphicsContext(), static_cast<uint>(rect.width), static_cast<uint>(rect.height));
std::free(filename);
}
#endif #endif
} }




+ 5
- 0
dpf/dgl/src/WindowPrivateData.hpp View File

@@ -77,6 +77,9 @@ struct Window::PrivateData : IdleCallback {
/** Whether to ignore idle callback requests, useful for temporary windows. */ /** Whether to ignore idle callback requests, useful for temporary windows. */
bool ignoreIdleCallbacks; bool ignoreIdleCallbacks;


/** Render to a picture file when non-null, automatically free+unset after saving. */
char* filenameToRenderInto;

#ifdef DISTRHO_OS_WINDOWS #ifdef DISTRHO_OS_WINDOWS
/** Selected file for openFileBrowser on windows, stored for fake async operation. */ /** Selected file for openFileBrowser on windows, stored for fake async operation. */
const char* win32SelectedFile; const char* win32SelectedFile;
@@ -162,6 +165,8 @@ struct Window::PrivateData : IdleCallback {
# endif # endif
#endif #endif


static void renderToPicture(const char* filename, const GraphicsContext& context, uint width, uint height);

// modal handling // modal handling
void startModal(); void startModal();
void stopModal(); void stopModal();


+ 6
- 1
dpf/dgl/src/nanovg/nanovg.c View File

@@ -817,9 +817,14 @@ int nvgCreateImageMem(NVGcontext* ctx, int imageFlags, unsigned char* data, int
return image; return image;
} }


int nvgCreateImageRaw(NVGcontext* ctx, int w, int h, int imageFlags, NVGtexture format, const unsigned char* data)
{
return ctx->params.renderCreateTexture(ctx->params.userPtr, format, w, h, imageFlags, data);
}

int nvgCreateImageRGBA(NVGcontext* ctx, int w, int h, int imageFlags, const unsigned char* data) int nvgCreateImageRGBA(NVGcontext* ctx, int w, int h, int imageFlags, const unsigned char* data)
{ {
return ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_RGBA, w, h, imageFlags, data);
return nvgCreateImageRaw(ctx, w, h, imageFlags, NVG_TEXTURE_RGBA, data);
} }


void nvgUpdateImage(NVGcontext* ctx, int image, const unsigned char* data) void nvgUpdateImage(NVGcontext* ctx, int image, const unsigned char* data)


+ 12
- 5
dpf/dgl/src/nanovg/nanovg.h View File

@@ -144,6 +144,14 @@ enum NVGimageFlags {
NVG_IMAGE_NEAREST = 1<<5, // Image interpolation is Nearest instead Linear NVG_IMAGE_NEAREST = 1<<5, // Image interpolation is Nearest instead Linear
}; };


enum NVGtexture {
NVG_TEXTURE_ALPHA,
NVG_TEXTURE_BGR,
NVG_TEXTURE_BGRA,
NVG_TEXTURE_RGB,
NVG_TEXTURE_RGBA,
};

// Begin drawing a new frame // Begin drawing a new frame
// Calls to nanovg drawing API should be wrapped in nvgBeginFrame() & nvgEndFrame() // Calls to nanovg drawing API should be wrapped in nvgBeginFrame() & nvgEndFrame()
// nvgBeginFrame() defines the size of the window to render to in relation currently // nvgBeginFrame() defines the size of the window to render to in relation currently
@@ -375,6 +383,10 @@ int nvgCreateImage(NVGcontext* ctx, const char* filename, int imageFlags);
// Returns handle to the image. // Returns handle to the image.
int nvgCreateImageMem(NVGcontext* ctx, int imageFlags, unsigned char* data, int ndata); int nvgCreateImageMem(NVGcontext* ctx, int imageFlags, unsigned char* data, int ndata);


// Creates image from specified image data and texture format.
// Returns handle to the image.
int nvgCreateImageRaw(NVGcontext* ctx, int w, int h, int imageFlags, NVGtexture format, const unsigned char* data);

// Creates image from specified image data. // Creates image from specified image data.
// Returns handle to the image. // Returns handle to the image.
int nvgCreateImageRGBA(NVGcontext* ctx, int w, int h, int imageFlags, const unsigned char* data); int nvgCreateImageRGBA(NVGcontext* ctx, int w, int h, int imageFlags, const unsigned char* data);
@@ -627,11 +639,6 @@ int nvgTextBreakLines(NVGcontext* ctx, const char* string, const char* end, floa
// //
// Internal Render API // Internal Render API
// //
enum NVGtexture {
NVG_TEXTURE_ALPHA = 0x01,
NVG_TEXTURE_RGBA = 0x02,
};

struct NVGscissor { struct NVGscissor {
float xform[6]; float xform[6];
float extent[2]; float extent[2];


+ 68
- 10
dpf/dgl/src/nanovg/nanovg_gl.h View File

@@ -761,9 +761,21 @@ static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int im
} }
#endif #endif


if (type == NVG_TEXTURE_RGBA)
switch (type)
{
case NVG_TEXTURE_BGR:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
break;
case NVG_TEXTURE_BGRA:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
break;
case NVG_TEXTURE_RGB:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
break;
case NVG_TEXTURE_RGBA:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
else
break;
default:
#if defined(NANOVG_GLES2) || defined (NANOVG_GL2) #if defined(NANOVG_GLES2) || defined (NANOVG_GL2)
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
#elif defined(NANOVG_GLES3) #elif defined(NANOVG_GLES3)
@@ -771,6 +783,8 @@ static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int im
#else #else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, data); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, data);
#endif #endif
break;
}


if (imageFlags & NVG_IMAGE_GENERATE_MIPMAPS) { if (imageFlags & NVG_IMAGE_GENERATE_MIPMAPS) {
if (imageFlags & NVG_IMAGE_NEAREST) { if (imageFlags & NVG_IMAGE_NEAREST) {
@@ -845,22 +859,50 @@ static int glnvg__renderUpdateTexture(void* uptr, int image, int x, int y, int w
glPixelStorei(GL_UNPACK_SKIP_ROWS, y); glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
#else #else
// No support for all of skip, need to update a whole row at a time. // No support for all of skip, need to update a whole row at a time.
if (tex->type == NVG_TEXTURE_RGBA)
switch (tex->type)
{
case NVG_TEXTURE_BGR:
data += y*tex->width*3;
break;
case NVG_TEXTURE_BGRA:
data += y*tex->width*4; data += y*tex->width*4;
else
break;
case NVG_TEXTURE_RGB:
data += y*tex->width*3;
break;
case NVG_TEXTURE_RGBA:
data += y*tex->width*4;
break;
default:
data += y*tex->width; data += y*tex->width;
break;
}
x = 0; x = 0;
w = tex->width; w = tex->width;
#endif #endif


if (tex->type == NVG_TEXTURE_RGBA)
switch (tex->type)
{
case NVG_TEXTURE_BGR:
glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_BGR, GL_UNSIGNED_BYTE, data);
break;
case NVG_TEXTURE_BGRA:
glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_BGRA, GL_UNSIGNED_BYTE, data);
break;
case NVG_TEXTURE_RGB:
glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_RGB, GL_UNSIGNED_BYTE, data);
break;
case NVG_TEXTURE_RGBA:
glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_RGBA, GL_UNSIGNED_BYTE, data); glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_RGBA, GL_UNSIGNED_BYTE, data);
else
break;
default:
#if defined(NANOVG_GLES2) || defined(NANOVG_GL2) #if defined(NANOVG_GLES2) || defined(NANOVG_GL2)
glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
#else #else
glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_RED, GL_UNSIGNED_BYTE, data); glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_RED, GL_UNSIGNED_BYTE, data);
#endif #endif
break;
}


glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
#ifndef NANOVG_GLES2 #ifndef NANOVG_GLES2
@@ -956,15 +998,31 @@ static int glnvg__convertPaint(GLNVGcontext* gl, GLNVGfragUniforms* frag, NVGpai
frag->type = NSVG_SHADER_FILLIMG; frag->type = NSVG_SHADER_FILLIMG;


#if NANOVG_GL_USE_UNIFORMBUFFER #if NANOVG_GL_USE_UNIFORMBUFFER
if (tex->type == NVG_TEXTURE_RGBA)
switch (tex->type)
{
case NVG_TEXTURE_BGR:
case NVG_TEXTURE_BGRA:
case NVG_TEXTURE_RGB:
case NVG_TEXTURE_RGBA:
frag->texType = (tex->flags & NVG_IMAGE_PREMULTIPLIED) ? 0 : 1; frag->texType = (tex->flags & NVG_IMAGE_PREMULTIPLIED) ? 0 : 1;
else
break;
default:
frag->texType = 2; frag->texType = 2;
break;
}
#else #else
if (tex->type == NVG_TEXTURE_RGBA)
switch (tex->type)
{
case NVG_TEXTURE_BGR:
case NVG_TEXTURE_BGRA:
case NVG_TEXTURE_RGB:
case NVG_TEXTURE_RGBA:
frag->texType = (tex->flags & NVG_IMAGE_PREMULTIPLIED) ? 0.0f : 1.0f; frag->texType = (tex->flags & NVG_IMAGE_PREMULTIPLIED) ? 0.0f : 1.0f;
else
break;
default:
frag->texType = 2.0f; frag->texType = 2.0f;
break;
}
#endif #endif
// printf("frag->texType = %d\n", frag->texType); // printf("frag->texType = %d\n", frag->texType);
} else { } else {


+ 1
- 1
dpf/distrho/DistrhoInfo.hpp View File

@@ -1,6 +1,6 @@
/* /*
* DISTRHO Plugin Framework (DPF) * 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 * 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
- 1
dpf/distrho/DistrhoPluginMain.cpp View File

@@ -1,6 +1,6 @@
/* /*
* DISTRHO Plugin Framework (DPF) * DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2016 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 * 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


+ 4
- 4
dpf/distrho/DistrhoPluginUtils.hpp View File

@@ -1,6 +1,6 @@
/* /*
* DISTRHO Plugin Framework (DPF) * 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 * 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
@@ -44,11 +44,11 @@ START_NAMESPACE_DISTRHO


Some important notes when using this class: Some important notes when using this class:
1. MidiEvent::frame retains its original value, but it is useless, do not use it. 1. MidiEvent::frame retains its original value, but it is useless, do not use it.
2. The class variables names are be the same as the default ones in the run function.
2. The class variable names are the same as the default ones in the run function.
Keep that in mind and try to avoid typos. :) Keep that in mind and try to avoid typos. :)
*/ */
class AudioMidiSyncHelper {
public:
struct AudioMidiSyncHelper
{
/** Parameters from the run function, adjusted for event sync */ /** Parameters from the run function, adjusted for event sync */
float* outputs[DISTRHO_PLUGIN_NUM_OUTPUTS]; float* outputs[DISTRHO_PLUGIN_NUM_OUTPUTS];
uint32_t frames; uint32_t frames;


+ 30
- 0
dpf/distrho/extra/String.hpp View File

@@ -618,6 +618,36 @@ public:
return *this; return *this;
} }


/*
* Create a new string where all non-basic characters are converted to '_'.
* @see toBasic()
*/
String asBasic() const noexcept
{
String s(*this);
return s.toBasic();
}

/*
* Create a new string where all ascii characters are converted lowercase.
* @see toLower()
*/
String asLower() const noexcept
{
String s(*this);
return s.toLower();
}

/*
* Create a new string where all ascii characters are converted to uppercase.
* @see toUpper()
*/
String asUpper() const noexcept
{
String s(*this);
return s.toUpper();
}

/* /*
* Direct access to the string buffer (read-only). * Direct access to the string buffer (read-only).
*/ */


+ 5
- 6
dpf/distrho/src/DistrhoPluginChecks.h View File

@@ -146,12 +146,11 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Enable full state if plugin exports presets // Enable full state if plugin exports presets


// FIXME
// #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
// # undef DISTRHO_PLUGIN_WANT_FULL_STATE
// # define DISTRHO_PLUGIN_WANT_FULL_STATE 1
// #endif
#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
# undef DISTRHO_PLUGIN_WANT_FULL_STATE
# define DISTRHO_PLUGIN_WANT_FULL_STATE 1
#endif


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Disable UI if DGL or External UI is not available // Disable UI if DGL or External UI is not available


+ 194
- 24
dpf/distrho/src/DistrhoPluginLV2export.cpp View File

@@ -332,6 +332,7 @@ void lv2_generate_ttl(const char* const basename)
pluginString += "@prefix doap: <http://usefulinc.com/ns/doap#> .\n"; pluginString += "@prefix doap: <http://usefulinc.com/ns/doap#> .\n";
pluginString += "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n"; pluginString += "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n";
pluginString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; pluginString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n";
pluginString += "@prefix midi: <" LV2_MIDI_PREFIX "> .\n";
pluginString += "@prefix mod: <http://moddevices.com/ns/mod#> .\n"; pluginString += "@prefix mod: <http://moddevices.com/ns/mod#> .\n";
pluginString += "@prefix opts: <" LV2_OPTIONS_PREFIX "> .\n"; pluginString += "@prefix opts: <" LV2_OPTIONS_PREFIX "> .\n";
pluginString += "@prefix pg: <" LV2_PORT_GROUPS_PREFIX "> .\n"; pluginString += "@prefix pg: <" LV2_PORT_GROUPS_PREFIX "> .\n";
@@ -341,6 +342,7 @@ void lv2_generate_ttl(const char* const basename)
#if DISTRHO_LV2_USE_EVENTS_IN || DISTRHO_LV2_USE_EVENTS_OUT #if DISTRHO_LV2_USE_EVENTS_IN || DISTRHO_LV2_USE_EVENTS_OUT
pluginString += "@prefix rsz: <" LV2_RESIZE_PORT_PREFIX "> .\n"; pluginString += "@prefix rsz: <" LV2_RESIZE_PORT_PREFIX "> .\n";
#endif #endif
pluginString += "@prefix spdx: <http://spdx.org/rdf/terms#> .\n";
#if DISTRHO_PLUGIN_HAS_UI #if DISTRHO_PLUGIN_HAS_UI
pluginString += "@prefix ui: <" LV2_UI_PREFIX "> .\n"; pluginString += "@prefix ui: <" LV2_UI_PREFIX "> .\n";
#endif #endif
@@ -368,11 +370,11 @@ void lv2_generate_ttl(const char* const basename)
// plugin // plugin
pluginString += "<" DISTRHO_PLUGIN_URI ">\n"; pluginString += "<" DISTRHO_PLUGIN_URI ">\n";
#ifdef DISTRHO_PLUGIN_LV2_CATEGORY #ifdef DISTRHO_PLUGIN_LV2_CATEGORY
pluginString += " a " DISTRHO_PLUGIN_LV2_CATEGORY ", lv2:Plugin ;\n";
pluginString += " a " DISTRHO_PLUGIN_LV2_CATEGORY ", lv2:Plugin, doap:Project ;\n";
#elif DISTRHO_PLUGIN_IS_SYNTH #elif DISTRHO_PLUGIN_IS_SYNTH
pluginString += " a lv2:InstrumentPlugin, lv2:Plugin ;\n";
pluginString += " a lv2:InstrumentPlugin, lv2:Plugin, doap:Project ;\n";
#else #else
pluginString += " a lv2:Plugin ;\n";
pluginString += " a lv2:Plugin, doap:Project ;\n";
#endif #endif
pluginString += "\n"; pluginString += "\n";


@@ -594,10 +596,13 @@ void lv2_generate_ttl(const char* const basename)
pluginString += " rsz:minimumSize " + String(DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE) + " ;\n"; pluginString += " rsz:minimumSize " + String(DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE) + " ;\n";
pluginString += " atom:bufferType atom:Sequence ;\n"; pluginString += " atom:bufferType atom:Sequence ;\n";
# if (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI) # if (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)
pluginString += " atom:supports <" LV2_ATOM__String "> ;\n";
pluginString += " atom:supports atom:String ;\n";
# endif # endif
# if DISTRHO_PLUGIN_WANT_MIDI_INPUT # if DISTRHO_PLUGIN_WANT_MIDI_INPUT
pluginString += " atom:supports <" LV2_MIDI__MidiEvent "> ;\n";
pluginString += " atom:supports midi:MidiEvent ;\n";
# endif
# if DISTRHO_PLUGIN_WANT_STATEFILES
pluginString += " atom:supports <" LV2_PATCH__Message "> ;\n";
# endif # endif
# if DISTRHO_PLUGIN_WANT_TIMEPOS # if DISTRHO_PLUGIN_WANT_TIMEPOS
pluginString += " atom:supports <" LV2_TIME__Position "> ;\n"; pluginString += " atom:supports <" LV2_TIME__Position "> ;\n";
@@ -615,10 +620,13 @@ void lv2_generate_ttl(const char* const basename)
pluginString += " rsz:minimumSize " + String(DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE) + " ;\n"; pluginString += " rsz:minimumSize " + String(DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE) + " ;\n";
pluginString += " atom:bufferType atom:Sequence ;\n"; pluginString += " atom:bufferType atom:Sequence ;\n";
# if (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI) # if (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)
pluginString += " atom:supports <" LV2_ATOM__String "> ;\n";
pluginString += " atom:supports atom:String ;\n";
# endif # endif
# if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT # if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
pluginString += " atom:supports <" LV2_MIDI__MidiEvent "> ;\n";
pluginString += " atom:supports midi:MidiEvent ;\n";
# endif
# if DISTRHO_PLUGIN_WANT_STATEFILES
pluginString += " atom:supports <" LV2_PATCH__Message "> ;\n";
# endif # endif
pluginString += " ] ;\n\n"; pluginString += " ] ;\n\n";
++portIndex; ++portIndex;
@@ -746,12 +754,22 @@ void lv2_generate_ttl(const char* const basename)
} }


if (j+1 == enumValues.count) if (j+1 == enumValues.count)
pluginString += " ] ;\n\n";
pluginString += " ] ;\n";
else else
pluginString += " ] ,\n"; pluginString += " ] ,\n";
} }
} }


// MIDI CC binding
if (const uint8_t midiCC = plugin.getParameterMidiCC(i))
{
char midiCCBuf[7];
snprintf(midiCCBuf, sizeof(midiCCBuf), "B0%02x00", midiCC);
pluginString += " midi:binding \"";
pluginString += midiCCBuf;
pluginString += "\"^^midi:MidiEvent ;\n";
}

// unit // unit
const String& unit(plugin.getParameterUnit(i)); const String& unit(plugin.getParameterUnit(i));


@@ -814,7 +832,7 @@ void lv2_generate_ttl(const char* const basename)
} }


// hints // hints
const uint32_t hints(plugin.getParameterHints(i));
const uint32_t hints = plugin.getParameterHints(i);


if (hints & kParameterIsBoolean) if (hints & kParameterIsBoolean)
{ {
@@ -832,8 +850,6 @@ void lv2_generate_ttl(const char* const basename)
pluginString += " <" LV2_KXSTUDIO_PROPERTIES__NonAutomable "> ;\n"; pluginString += " <" LV2_KXSTUDIO_PROPERTIES__NonAutomable "> ;\n";
} }


// TODO midiCC

// group // group
const uint32_t groupId = plugin.getParameterGroupId(i); const uint32_t groupId = plugin.getParameterGroupId(i);


@@ -895,13 +911,154 @@ void lv2_generate_ttl(const char* const basename)
{ {
const String license(plugin.getLicense()); const String license(plugin.getLicense());


// TODO always convert to URL, do best-guess based on known licenses
// Using URL as license
if (license.contains("://")) if (license.contains("://"))
{
pluginString += " doap:license <" + license + "> ;\n\n"; pluginString += " doap:license <" + license + "> ;\n\n";
}
// String contaning quotes, use as-is
else if (license.contains('"')) else if (license.contains('"'))
{
pluginString += " doap:license \"\"\"" + license + "\"\"\" ;\n\n"; pluginString += " doap:license \"\"\"" + license + "\"\"\" ;\n\n";
}
// Regular license string, convert to URL as much as we can
else else
pluginString += " doap:license \"" + license + "\" ;\n\n";
{
const String uplicense(license.asUpper());

// for reference, see https://spdx.org/licenses/

// common licenses
/**/ if (uplicense == "AGPL-1.0-ONLY" ||
uplicense == "AGPL1" ||
uplicense == "AGPLV1")
{
pluginString += " doap:license <http://spdx.org/licenses/AGPL-1.0-only.html> ;\n\n";
}
else if (uplicense == "AGPL-1.0-OR-LATER" ||
uplicense == "AGPL1+" ||
uplicense == "AGPLV1+")
{
pluginString += " doap:license <http://spdx.org/licenses/AGPL-1.0-or-later.html> ;\n\n";
}
else if (uplicense == "AGPL-3.0-ONLY" ||
uplicense == "AGPL3" ||
uplicense == "AGPLV3")
{
pluginString += " doap:license <http://spdx.org/licenses/AGPL-3.0-only.html> ;\n\n";
}
else if (uplicense == "AGPL-3.0-OR-LATER" ||
uplicense == "AGPL3+" ||
uplicense == "AGPLV3+")
{
pluginString += " doap:license <http://spdx.org/licenses/AGPL-3.0-or-later.html> ;\n\n";
}
else if (uplicense == "APACHE-2.0" ||
uplicense == "APACHE2" ||
uplicense == "APACHE-2")
{
pluginString += " doap:license <http://spdx.org/licenses/Apache-2.0.html> ;\n\n";
}
else if (uplicense == "BSD-2-CLAUSE" ||
uplicense == "BSD2" ||
uplicense == "BSD-2")
{
pluginString += " doap:license <http://spdx.org/licenses/BSD-2-Clause.html> ;\n\n";
}
else if (uplicense == "BSD-3-CLAUSE" ||
uplicense == "BSD3" ||
uplicense == "BSD-3")
{
pluginString += " doap:license <http://spdx.org/licenses/BSD-3-Clause.html> ;\n\n";
}
else if (uplicense == "GPL-2.0-ONLY" ||
uplicense == "GPL2" ||
uplicense == "GPLV2")
{
pluginString += " doap:license <http://spdx.org/licenses/GPL-2.0-only.html> ;\n\n";
}
else if (uplicense == "GPL-2.0-OR-LATER" ||
uplicense == "GPL2+" ||
uplicense == "GPLV2+" ||
uplicense == "GPL V2+")
{
pluginString += " doap:license <http://spdx.org/licenses/GPL-2.0-or-later.html> ;\n\n";
}
else if (uplicense == "GPL-3.0-ONLY" ||
uplicense == "GPL3" ||
uplicense == "GPLV3")
{
pluginString += " doap:license <http://spdx.org/licenses/GPL-3.0-only.html> ;\n\n";
}
else if (uplicense == "GPL-3.0-OR-LATER" ||
uplicense == "GPL3+" ||
uplicense == "GPLV3+" ||
uplicense == "GPL V3+")
{
pluginString += " doap:license <http://spdx.org/licenses/GPL-3.0-or-later.html> ;\n\n";
}
else if (uplicense == "ISC")
{
pluginString += " doap:license <http://spdx.org/licenses/ISC.html> ;\n\n";
}
else if (uplicense == "LGPL-2.0-ONLY" ||
uplicense == "LGPL2" ||
uplicense == "LGPLV2")
{
pluginString += " doap:license <http://spdx.org/licenses/LGPL-2.0-only.html> ;\n\n";
}
else if (uplicense == "LGPL-2.0-OR-LATER" ||
uplicense == "LGPL2+" ||
uplicense == "LGPLV2+")
{
pluginString += " doap:license <http://spdx.org/licenses/LGPL-2.0-or-later.html> ;\n\n";
}
else if (uplicense == "LGPL-2.1-ONLY" ||
uplicense == "LGPL2.1" ||
uplicense == "LGPLV2.1")
{
pluginString += " doap:license <http://spdx.org/licenses/LGPL-2.1-only.html> ;\n\n";
}
else if (uplicense == "LGPL-2.1-OR-LATER" ||
uplicense == "LGPL2.1+" ||
uplicense == "LGPLV2.1+")
{
pluginString += " doap:license <http://spdx.org/licenses/LGPL-2.1-or-later.html> ;\n\n";
}
else if (uplicense == "LGPL-3.0-ONLY" ||
uplicense == "LGPL3" ||
uplicense == "LGPLV3")
{
pluginString += " doap:license <http://spdx.org/licenses/LGPL-2.0-only.html> ;\n\n";
}
else if (uplicense == "LGPL-3.0-OR-LATER" ||
uplicense == "LGPL3+" ||
uplicense == "LGPLV3+")
{
pluginString += " doap:license <http://spdx.org/licenses/LGPL-3.0-or-later.html> ;\n\n";
}
else if (uplicense == "MIT")
{
pluginString += " doap:license <http://spdx.org/licenses/MIT.html> ;\n\n";
}

// generic fallbacks
else if (uplicense.startsWith("GPL"))
{
pluginString += " doap:license <https://opensource.org/licenses/gpl-license> ;\n\n";
}
else if (uplicense.startsWith("LGPL"))
{
pluginString += " doap:license <https://opensource.org/licenses/lgpl-license> ;\n\n";
}

// unknown or not handled yet, log a warning
else
{
d_stderr("Unknown license string '%s'", license.buffer());
pluginString += " doap:license \"" + license + "\" ;\n\n";
}
}
} }


// developer // developer
@@ -1037,7 +1194,10 @@ void lv2_generate_ttl(const char* const basename)
presetsString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; presetsString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n";
presetsString += "@prefix pset: <" LV2_PRESETS_PREFIX "> .\n"; presetsString += "@prefix pset: <" LV2_PRESETS_PREFIX "> .\n";
# if DISTRHO_PLUGIN_WANT_STATE # if DISTRHO_PLUGIN_WANT_STATE
presetsString += "@prefix owl: <http://www.w3.org/2002/07/owl#> .\n";
presetsString += "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n";
presetsString += "@prefix state: <" LV2_STATE_PREFIX "> .\n"; presetsString += "@prefix state: <" LV2_STATE_PREFIX "> .\n";
presetsString += "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .\n";
# endif # endif
presetsString += "\n"; presetsString += "\n";


@@ -1045,8 +1205,13 @@ void lv2_generate_ttl(const char* const basename)
const uint32_t numPrograms = plugin.getProgramCount(); const uint32_t numPrograms = plugin.getProgramCount();
# if DISTRHO_PLUGIN_WANT_FULL_STATE # if DISTRHO_PLUGIN_WANT_FULL_STATE
const uint32_t numStates = plugin.getStateCount(); const uint32_t numStates = plugin.getStateCount();
const bool valid = numParameters != 0 || numStates != 0;
# else
const bool valid = numParameters != 0;
# endif # endif


DISTRHO_CUSTOM_SAFE_ASSERT_RETURN("Programs require parameters or full state", valid, presetsFile.close());

const String presetSeparator(std::strstr(DISTRHO_PLUGIN_URI, "#") != nullptr ? ":" : "#"); const String presetSeparator(std::strstr(DISTRHO_PLUGIN_URI, "#") != nullptr ? ":" : "#");


char strBuf[0xff+1]; char strBuf[0xff+1];
@@ -1054,6 +1219,22 @@ void lv2_generate_ttl(const char* const basename)


String presetString; String presetString;


# if DISTRHO_PLUGIN_WANT_FULL_STATE
for (uint32_t i=0; i<numStates; ++i)
{
# if DISTRHO_PLUGIN_WANT_STATEFILES
if (plugin.isStateFile(i))
continue;
# endif
presetString = "<" DISTRHO_PLUGIN_LV2_STATE_PREFIX + plugin.getStateKey(i) + ">\n";
presetString += " a owl:DatatypeProperty ;\n";
presetString += " rdfs:label \"Plugin state key-value string pair\" ;\n";
presetString += " rdfs:domain state:State ;\n";
presetString += " rdfs:range xsd:string .\n\n";
presetsString += presetString;
}
# endif

for (uint32_t i=0; i<numPrograms; ++i) for (uint32_t i=0; i<numPrograms; ++i)
{ {
std::snprintf(strBuf, 0xff, "%03i", i+1); std::snprintf(strBuf, 0xff, "%03i", i+1);
@@ -1062,17 +1243,6 @@ void lv2_generate_ttl(const char* const basename)


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";
for (uint32_t j=0; j<numStates; ++j) for (uint32_t j=0; j<numStates; ++j)


+ 17
- 1
dpf/distrho/src/DistrhoPluginVST2.cpp View File

@@ -44,6 +44,7 @@
#include <clocale> #include <clocale>
#include <map> #include <map>
#include <string> #include <string>
#include <vector>


#if VESTIGE_HEADER #if VESTIGE_HEADER
# include "vestige/vestige.h" # include "vestige/vestige.h"
@@ -1635,6 +1636,20 @@ static void vst_processReplacingCallback(AEffect* effect, float** inputs, float*
#undef validPlugin #undef validPlugin
#undef vstObjectPtr #undef vstObjectPtr


static struct Cleanup {
std::vector<AEffect*> effects;

~Cleanup()
{
for (std::vector<AEffect*>::iterator it = effects.begin(), end = effects.end(); it != end; ++it)
{
AEffect* const effect = *it;
delete (VstObject*)effect->object;
delete effect;
}
}
} sCleanup;

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


END_NAMESPACE_DISTRHO END_NAMESPACE_DISTRHO
@@ -1714,12 +1729,13 @@ const AEffect* VSTPluginMain(audioMasterCallback audioMaster)
effect->processReplacing = vst_processReplacingCallback; effect->processReplacing = vst_processReplacingCallback;


// pointers // pointers
VstObject* const obj(new VstObject());
VstObject* const obj = new VstObject();
obj->audioMaster = audioMaster; obj->audioMaster = audioMaster;
obj->plugin = nullptr; obj->plugin = nullptr;


// done // done
effect->object = obj; effect->object = obj;
sCleanup.effects.push_back(effect);


return effect; return effect;
} }


+ 7
- 2
dpf/tests/Makefile View File

@@ -31,6 +31,7 @@ endif
ifeq ($(HAVE_OPENGL),true) ifeq ($(HAVE_OPENGL),true)
MANUAL_TESTS += Demo.opengl MANUAL_TESTS += Demo.opengl
MANUAL_TESTS += FileBrowserDialog MANUAL_TESTS += FileBrowserDialog
MANUAL_TESTS += NanoImage
MANUAL_TESTS += NanoSubWidgets MANUAL_TESTS += NanoSubWidgets
UNIT_TESTS += Window.opengl UNIT_TESTS += Window.opengl
endif endif
@@ -140,11 +141,15 @@ clean:
$(SILENT)$(CXX) $^ $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(VULKAN_LIBS) -o $@ $(SILENT)$(CXX) $^ $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(VULKAN_LIBS) -o $@


../build/tests/FileBrowserDialog$(APP_EXT): ../build/tests/FileBrowserDialog.cpp.o ../build/libdgl-opengl.a ../build/tests/FileBrowserDialog$(APP_EXT): ../build/tests/FileBrowserDialog.cpp.o ../build/libdgl-opengl.a
@echo "Linking Demo (OpenGL)"
@echo "Linking FileBrowserDialog (OpenGL)"
$(SILENT)$(CXX) $^ $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@

../build/tests/NanoImage$(APP_EXT): ../build/tests/NanoImage.cpp.o ../build/libdgl-opengl.a
@echo "Linking NanoImage (OpenGL)"
$(SILENT)$(CXX) $^ $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ $(SILENT)$(CXX) $^ $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@


../build/tests/NanoSubWidgets$(APP_EXT): ../build/tests/NanoSubWidgets.cpp.o ../build/libdgl-opengl.a ../build/tests/NanoSubWidgets$(APP_EXT): ../build/tests/NanoSubWidgets.cpp.o ../build/libdgl-opengl.a
@echo "Linking Demo (OpenGL)"
@echo "Linking NanoSubWidgets (OpenGL)"
$(SILENT)$(CXX) $^ $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ $(SILENT)$(CXX) $^ $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@


# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------


+ 229
- 0
dpf/tests/NanoImage.cpp View File

@@ -0,0 +1,229 @@
/*
* DISTRHO Plugin Framework (DPF)
* 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
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "tests.hpp"

#include "dgl/NanoVG.hpp"

START_NAMESPACE_DGL

// --------------------------------------------------------------------------------------------------------------------
// Images

#include "images_res/CatPics.cpp"

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

class NanoImageExample : public NanoStandaloneWindow,
public IdleCallback
{
static const int kImg1y = 0;
static const int kImg2y = 500/2-CatPics::cat2Height/2;
static const int kImg3x = 400/3-CatPics::cat3Width/3;

static const int kImg1max = 500-CatPics::cat1Width;
static const int kImg2max = 500-CatPics::cat2Width;
static const int kImg3max = 400-CatPics::cat3Height;

static const int kImgFlags = IMAGE_GENERATE_MIPMAPS | IMAGE_REPEAT_X;

int imgTop1st, imgTop2nd, imgTop3rd;
int img1x, img2x, img3y;
bool img1rev, img2rev, img3rev;
NanoImage img1, img2, img3;

public:
NanoImageExample(Application& app)
: NanoStandaloneWindow(app),
imgTop1st(1),
imgTop2nd(2),
imgTop3rd(3),
img1x(0),
img2x(kImg2max),
img3y(kImg3max),
img1rev(false),
img2rev(true),
img3rev(true),
img1(createImageFromRawMemory(CatPics::cat1Width, CatPics::cat1Height, (uchar*)CatPics::cat1Data, kImgFlags, kImageFormatBGR)),
img2(createImageFromRawMemory(CatPics::cat2Width, CatPics::cat2Height, (uchar*)CatPics::cat2Data, kImgFlags, kImageFormatBGR)),
img3(createImageFromRawMemory(CatPics::cat3Width, CatPics::cat3Height, (uchar*)CatPics::cat3Data, kImgFlags, kImageFormatBGR))
{
DISTRHO_SAFE_ASSERT(img1.isValid());
DISTRHO_SAFE_ASSERT(img2.isValid());
DISTRHO_SAFE_ASSERT(img3.isValid());

DISTRHO_SAFE_ASSERT_UINT2(img1.getSize().getWidth() == CatPics::cat1Width,
img1.getSize().getWidth(), CatPics::cat1Width);

DISTRHO_SAFE_ASSERT_UINT2(img1.getSize().getHeight() == CatPics::cat1Height,
img1.getSize().getHeight(), CatPics::cat1Height);

DISTRHO_SAFE_ASSERT_UINT2(img2.getSize().getWidth() == CatPics::cat2Width,
img2.getSize().getWidth(), CatPics::cat2Width);

DISTRHO_SAFE_ASSERT_UINT2(img2.getSize().getHeight() == CatPics::cat2Height,
img2.getSize().getHeight(), CatPics::cat2Height);

DISTRHO_SAFE_ASSERT_UINT2(img3.getSize().getWidth() == CatPics::cat3Width,
img3.getSize().getWidth(), CatPics::cat3Width);

DISTRHO_SAFE_ASSERT_UINT2(img3.getSize().getHeight() == CatPics::cat3Height,
img3.getSize().getHeight(), CatPics::cat3Height);

setResizable(true);
setSize(500, 500);
// setGeometryConstraints(500, 500, false);
setTitle("NanoImage");
done();

addIdleCallback(this);
}

protected:
void onNanoDisplay() override
{
// bottom image
beginPath();
fillPaint(setupImagePaint(imgTop3rd));
fill();

// middle image
beginPath();
fillPaint(setupImagePaint(imgTop2nd));
fill();

// top image
beginPath();
fillPaint(setupImagePaint(imgTop1st));
fill();
}

void idleCallback() noexcept override
{
if (img1rev)
{
img1x -= 2;
if (img1x <= -50)
{
img1rev = false;
setNewTopImg(1);
}
}
else
{
img1x += 2;
if (img1x >= kImg1max+50)
{
img1rev = true;
setNewTopImg(1);
}
}

if (img2rev)
{
img2x -= 1;
if (img2x <= -50)
{
img2rev = false;
setNewTopImg(2);
}
}
else
{
img2x += 4;
if (img2x >= kImg2max+50)
{
img2rev = true;
setNewTopImg(2);
}
}

if (img3rev)
{
img3y -= 3;
if (img3y <= -50)
{
img3rev = false;
setNewTopImg(3);
}
}
else
{
img3y += 3;
if (img3y >= kImg3max+50)
{
img3rev = true;
setNewTopImg(3);
}
}

repaint();
}

private:
Paint setupImagePaint(const int imgId) noexcept
{
switch (imgId)
{
case 1:
rect(img1x, kImg1y, CatPics::cat1Width, CatPics::cat1Height);
return imagePattern(img1x, kImg1y, CatPics::cat1Width, CatPics::cat1Height, 0, img1, 1.0f);
case 2:
rect(img2x, kImg2y, CatPics::cat2Width, CatPics::cat2Height);
return imagePattern(img2x, kImg2y, CatPics::cat2Width, CatPics::cat2Height, 0, img2, 1.0f);
case 3:
rect(kImg3x, img3y, CatPics::cat3Width, CatPics::cat3Height);
return imagePattern(kImg3x, img3y, CatPics::cat3Width, CatPics::cat3Height, 0, img3, 1.0f);
};

return Paint();
}

void setNewTopImg(const int imgId) noexcept
{
if (imgTop1st == imgId)
return;

if (imgTop2nd == imgId)
{
imgTop2nd = imgTop1st;
imgTop1st = imgId;
return;
}

imgTop3rd = imgTop2nd;
imgTop2nd = imgTop1st;
imgTop1st = imgId;
}
};

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

END_NAMESPACE_DGL

int main()
{
USE_NAMESPACE_DGL;

Application app(true);
NanoImageExample win(app);
win.show();
app.exec();

return 0;
}

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

+ 4
- 4
dpf/utils/lv2-ttl-generator/GNUmakefile View File

@@ -9,19 +9,19 @@ ifeq ($(WINDOWS),true)
build: ../lv2_ttl_generator.exe build: ../lv2_ttl_generator.exe


../lv2_ttl_generator.exe: lv2_ttl_generator.c ../lv2_ttl_generator.exe: lv2_ttl_generator.c
$(CC) $< $(CFLAGS) -o $@ $(LDFLAGS) -static
$(CC) $< $(BUILD_C_FLAGS) -o $@ $(LINK_FLAGS) -static
touch ../lv2_ttl_generator touch ../lv2_ttl_generator


else # WINDOWS else # WINDOWS


ifneq ($(HAIKU),true)
LDFLAGS += -ldl
ifneq ($(HAIKU_OR_MACOS_OR_WINDOWS),true)
LINK_FLAGS += -ldl
endif endif


build: ../lv2_ttl_generator build: ../lv2_ttl_generator


../lv2_ttl_generator: lv2_ttl_generator.c ../lv2_ttl_generator: lv2_ttl_generator.c
$(CC) $< $(CFLAGS) -o $@ $(LDFLAGS)
$(CC) $< $(BUILD_C_FLAGS) -o $@ $(LINK_FLAGS)


endif # WINDOWS endif # WINDOWS




+ 3
- 0
dpf/utils/symbols/dssi.def View File

@@ -0,0 +1,3 @@
EXPORTS
ladspa_descriptor
dssi_descriptor

+ 2
- 0
dpf/utils/symbols/dssi.exp View File

@@ -0,0 +1,2 @@
_ladspa_descriptor
_dssi_descriptor

+ 4
- 0
dpf/utils/symbols/dssi.version View File

@@ -0,0 +1,4 @@
{
global: ladspa_descriptor; dssi_descriptor;
local: *;
};

+ 2
- 0
dpf/utils/symbols/ladspa.def View File

@@ -0,0 +1,2 @@
EXPORTS
ladspa_descriptor

+ 1
- 0
dpf/utils/symbols/ladspa.exp View File

@@ -0,0 +1 @@
_ladspa_descriptor

+ 4
- 0
dpf/utils/symbols/ladspa.version View File

@@ -0,0 +1,4 @@
{
global: ladspa_descriptor;
local: *;
};

+ 3
- 0
dpf/utils/symbols/lv2-dsp.def View File

@@ -0,0 +1,3 @@
EXPORTS
lv2_descriptor
lv2_generate_ttl

+ 2
- 0
dpf/utils/symbols/lv2-dsp.exp View File

@@ -0,0 +1,2 @@
_lv2_descriptor
_lv2_generate_ttl

+ 4
- 0
dpf/utils/symbols/lv2-dsp.version View File

@@ -0,0 +1,4 @@
{
global: lv2_descriptor; lv2_generate_ttl;
local: *;
};

+ 2
- 0
dpf/utils/symbols/lv2-ui.def View File

@@ -0,0 +1,2 @@
EXPORTS
lv2ui_descriptor

+ 1
- 0
dpf/utils/symbols/lv2-ui.exp View File

@@ -0,0 +1 @@
_lv2ui_descriptor

+ 4
- 0
dpf/utils/symbols/lv2-ui.version View File

@@ -0,0 +1,4 @@
{
global: lv2ui_descriptor;
local: *;
};

+ 4
- 0
dpf/utils/symbols/lv2.def View File

@@ -0,0 +1,4 @@
EXPORTS
lv2_descriptor
lv2ui_descriptor
lv2_generate_ttl

+ 3
- 0
dpf/utils/symbols/lv2.exp View File

@@ -0,0 +1,3 @@
_lv2_descriptor
_lv2ui_descriptor
_lv2_generate_ttl

+ 4
- 0
dpf/utils/symbols/lv2.version View File

@@ -0,0 +1,4 @@
{
global: lv2_descriptor; lv2ui_descriptor; lv2_generate_ttl;
local: *;
};

+ 3
- 0
dpf/utils/symbols/vst2.def View File

@@ -0,0 +1,3 @@
EXPORTS
VSTPluginMain
main=VSTPluginMain

+ 1
- 0
dpf/utils/symbols/vst2.exp View File

@@ -0,0 +1 @@
_VSTPluginMain

+ 4
- 0
dpf/utils/symbols/vst2.version View File

@@ -0,0 +1,4 @@
{
global: VSTPluginMain; main;
local: *;
};

+ 4
- 0
dpf/utils/symbols/vst3.def View File

@@ -0,0 +1,4 @@
EXPORTS
GetPluginFactory
InitDll
ExitDll

+ 3
- 0
dpf/utils/symbols/vst3.exp View File

@@ -0,0 +1,3 @@
_GetPluginFactory
_bundleEntry
_bundleExit

+ 4
- 0
dpf/utils/symbols/vst3.version View File

@@ -0,0 +1,4 @@
{
global: GetPluginFactory; ModuleEntry; ModuleExit;
local: *;
};

+ 41
- 0
dpf/utils/valgrind-dpf.supp View File

@@ -0,0 +1,41 @@
{
libdl is full of leaks
Memcheck:Leak
...
fun:_dl_open
...
}
{
libdl is full of leaks
Memcheck:Leak
...
fun:_dl_close
...
}
{
libdl is full of leaks
Memcheck:Leak
...
fun:_dl_init
}
{
libdl is full of leaks
Memcheck:Leak
fun:calloc
fun:allocate_dtv
fun:_dl_allocate_tls
...
}
{
libdl is full of leaks
Memcheck:Leak
...
fun:call_init.part.0
}
{
ignore XInitThreads
Memcheck:Leak
...
fun:XInitThreads
...
}

+ 0
- 18
plugins/Nekobi/DistrhoPluginNekobi.cpp View File

@@ -135,7 +135,6 @@ DistrhoPluginNekobi::DistrhoPluginNekobi()
fParams.decay = 75.0f; fParams.decay = 75.0f;
fParams.accent = 25.0f; fParams.accent = 25.0f;
fParams.volume = 75.0f; fParams.volume = 75.0f;
fParams.bypass = false;
// Internal stuff // Internal stuff
fSynth.waveform = 0.0f; fSynth.waveform = 0.0f;
@@ -251,9 +250,6 @@ void DistrhoPluginNekobi::initParameter(uint32_t index, Parameter& parameter)
parameter.ranges.max = 100.0f; parameter.ranges.max = 100.0f;
parameter.midiCC = 7; //Volume parameter.midiCC = 7; //Volume
break; break;
case paramBypass:
parameter.initDesignation(kParameterDesignationBypass);
break;
} }
} }
@@ -280,8 +276,6 @@ float DistrhoPluginNekobi::getParameterValue(uint32_t index) const
return fParams.accent; return fParams.accent;
case paramVolume: case paramVolume:
return fParams.volume; return fParams.volume;
case paramBypass:
return fParams.bypass ? 1.0f : 0.0f;
} }
return 0.0f; return 0.0f;
@@ -331,14 +325,6 @@ void DistrhoPluginNekobi::setParameterValue(uint32_t index, float value)
fSynth.volume = value/100.0f; fSynth.volume = value/100.0f;
DISTRHO_SAFE_ASSERT(fSynth.volume >= 0.0f && fSynth.volume <= 1.0f); DISTRHO_SAFE_ASSERT(fSynth.volume >= 0.0f && fSynth.volume <= 1.0f);
break; break;
case paramBypass: {
const bool bypass = (value > 0.5f);
if (fParams.bypass != bypass)
{
fParams.bypass = bypass;
nekobee_synth_all_voices_off(&fSynth);
}
} break;
} }
} }
@@ -374,10 +360,6 @@ void DistrhoPluginNekobi::run(const float**, float** outputs, uint32_t frames, c
return; return;
} }
// ignore midi input if bypassed
if (fParams.bypass)
midiEventCount = 0;
while (framesDone < frames) while (framesDone < frames)
{ {
if (fSynth.nugget_remains == 0) if (fSynth.nugget_remains == 0)


+ 0
- 2
plugins/Nekobi/DistrhoPluginNekobi.hpp View File

@@ -42,7 +42,6 @@ public:
paramDecay, paramDecay,
paramAccent, paramAccent,
paramVolume, paramVolume,
paramBypass,
paramCount paramCount
}; };
@@ -118,7 +117,6 @@ private:
float decay; float decay;
float accent; float accent;
float volume; float volume;
bool bypass;
} fParams; } fParams;
nekobee_synth_t fSynth; nekobee_synth_t fSynth;


+ 3
- 0
plugins/ProM/DistrhoUIProM.cpp View File

@@ -96,6 +96,9 @@ DistrhoUIProM::DistrhoUIProM()


DistrhoUIProM::~DistrhoUIProM() DistrhoUIProM::~DistrhoUIProM()
{ {
if (fPM == nullptr)
return;

if (DistrhoPluginProM* const dspPtr = (DistrhoPluginProM*)getPluginInstancePointer()) if (DistrhoPluginProM* const dspPtr = (DistrhoPluginProM*)getPluginInstancePointer())
{ {
const MutexLocker csm(dspPtr->fMutex); const MutexLocker csm(dspPtr->fMutex);


+ 2
- 2
plugins/glBars/DistrhoPluginGLBars.cpp View File

@@ -74,8 +74,8 @@ void DistrhoPluginGLBars::initParameter(uint32_t index, Parameter& parameter)
parameter.name = "X"; parameter.name = "X";
parameter.symbol = "x"; parameter.symbol = "x";
parameter.unit = ""; parameter.unit = "";
parameter.ranges.def = -4.0f;
parameter.ranges.min = 0.0f;
parameter.ranges.def = 0.0f;
parameter.ranges.min = -4.0f;
parameter.ranges.max = 4.0f; parameter.ranges.max = 4.0f;
break; break;


+ 7
- 1
plugins/glBars/DistrhoUIGLBars.cpp View File

@@ -26,13 +26,17 @@ START_NAMESPACE_DISTRHO
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


DistrhoUIGLBars::DistrhoUIGLBars() DistrhoUIGLBars::DistrhoUIGLBars()
: UI(512, 512)
: UI(512, 512),
fInitialized(false)
{ {
setGeometryConstraints(256, 256, true); setGeometryConstraints(256, 256, true);
} }


DistrhoUIGLBars::~DistrhoUIGLBars() DistrhoUIGLBars::~DistrhoUIGLBars()
{ {
if (! fInitialized)
return;

if (DistrhoPluginGLBars* const dspPtr = (DistrhoPluginGLBars*)getPluginInstancePointer()) if (DistrhoPluginGLBars* const dspPtr = (DistrhoPluginGLBars*)getPluginInstancePointer())
{ {
const MutexLocker csm(dspPtr->fMutex); const MutexLocker csm(dspPtr->fMutex);
@@ -81,6 +85,8 @@ void DistrhoUIGLBars::uiIdle()
if (dspPtr->fState != nullptr) if (dspPtr->fState != nullptr)
return; return;


fInitialized = true;

const MutexLocker csm(dspPtr->fMutex); const MutexLocker csm(dspPtr->fMutex);
dspPtr->fState = &fState; dspPtr->fState = &fState;
} }


+ 1
- 0
plugins/glBars/DistrhoUIGLBars.hpp View File

@@ -53,6 +53,7 @@ protected:
bool onKeyboard(const KeyboardEvent&) override; bool onKeyboard(const KeyboardEvent&) override;


private: private:
bool fInitialized;
glBarsState fState; glBarsState fState;


DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DistrhoUIGLBars) DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DistrhoUIGLBars)


Loading…
Cancel
Save