Browse Source

Merge pull request #13 from cameronleger/v0.6-linux-lglw

V0.6 linux lglw
pull/1639/head
bsp2 GitHub 6 years ago
parent
commit
6c1e39c40e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 2764 additions and 35 deletions
  1. +378
    -31
      dep/lglw/lglw_linux.c
  2. +1
    -1
      other/vst2_debug_host/makefile.linux
  3. +121
    -2
      other/vst2_debug_host/vst2_debug_host.cpp
  4. +4
    -0
      other/vst2_lglw_debug_plugin/.gitignore
  5. +266
    -0
      other/vst2_lglw_debug_plugin/M3dB.xcodeproj/project.pbxproj
  6. +7
    -0
      other/vst2_lglw_debug_plugin/M3dB.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  7. +5
    -0
      other/vst2_lglw_debug_plugin/M3dB.xcodeproj/project.xcworkspace/xcuserdata/ypujante.xcuserdatad/xcschemes/xcschememanagement.plist
  8. +22
    -0
      other/vst2_lglw_debug_plugin/M3dB.xcodeproj/xcuserdata/ypujante.xcuserdatad/xcschemes/M3dB - Debug.xcscheme
  9. +22
    -0
      other/vst2_lglw_debug_plugin/M3dB.xcodeproj/xcuserdata/ypujante.xcuserdatad/xcschemes/M3dB - Release.xcscheme
  10. +19
    -0
      other/vst2_lglw_debug_plugin/M3dB.xcodeproj/xcuserdata/ypujante.xcuserdatad/xcschemes/xcschememanagement.plist
  11. +26
    -0
      other/vst2_lglw_debug_plugin/M3dB/Info.plist
  12. +19
    -0
      other/vst2_lglw_debug_plugin/makefile.linux
  13. +458
    -0
      other/vst2_lglw_debug_plugin/plugin.cpp
  14. +615
    -0
      other/vst2_lglw_debug_plugin/plugin.cpp__DUAL_WIN_CONTEXT_OK
  15. +527
    -0
      other/vst2_lglw_debug_plugin/plugin.cpp__SIMPLE
  16. +31
    -0
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db.sln
  17. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/dllmain.cpp
  18. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/m3db.cpp
  19. +167
    -0
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/m3db.vcxproj
  20. +33
    -0
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/m3db.vcxproj.filters
  21. +4
    -0
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/m3db.vcxproj.user
  22. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/stdafx.cpp
  23. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/stdafx.h
  24. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/targetver.h
  25. +5
    -0
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/m3db.Build.CppClean.log
  26. +2
    -0
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/m3db.log
  27. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/m3db.tlog/CL.command.1.tlog
  28. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/m3db.tlog/CL.read.1.tlog
  29. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/m3db.tlog/CL.write.1.tlog
  30. +2
    -0
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/m3db.tlog/m3db.lastbuildstate
  31. +0
    -0
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/m3db.tlog/unsuccessfulbuild
  32. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/vc141.idb
  33. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/vc141.pdb
  34. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/lglw_windows.obj
  35. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/lglw_windows_cpp.obj
  36. +15
    -0
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.Build.CppClean.log
  37. +8
    -0
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.log
  38. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/CL.command.1.tlog
  39. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/CL.read.1.tlog
  40. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/CL.write.1.tlog
  41. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/link.command.1.tlog
  42. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/link.read.1.tlog
  43. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/link.write.1.tlog
  44. +2
    -0
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/m3db.lastbuildstate
  45. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/m3db.write.1u.tlog
  46. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/plugin.obj
  47. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/x64/Release/m3db.iobj
  48. BIN
      other/vst2_lglw_debug_plugin/vs2017/m3db/x64/Release/m3db.ipdb
  49. +5
    -1
      src/util/logger.cpp

+ 378
- 31
dep/lglw/lglw_linux.c View File

@@ -24,7 +24,7 @@
* ---- info : This is part of the "lglw" package.
* ----
* ---- created: 04Aug2018
* ---- changed: 05Aug2018, 06Aug2018, 07Aug2018, 08Aug2018, 09Aug2018, 18Aug2018, 10Oct2018
* ---- changed: 05Aug2018, 06Aug2018, 07Aug2018, 08Aug2018, 09Aug2018, 18Aug2018, 10Oct2018, 16Oct2018
* ----
* ----
*/
@@ -35,6 +35,13 @@
#include <stdio.h>
#include <string.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>

#include <GL/gl.h>
#include <GL/glx.h>

#define Dprintf if(0);else printf
// #define Dprintf if(1);else printf

@@ -57,18 +64,29 @@

// ---------------------------------------------------------------------------- structs and typedefs
typedef struct lglw_int_s {
void *user_data; // arbitrary user data
void *user_data; // arbitrary user data
Display *xdsp;
XVisualInfo *vi;
Colormap cmap;
Window parent_xwnd; // created by host

struct {
lglw_vec2i_t size;
Window xwnd;
} hidden;

struct {
lglw_vec2i_t size;
Window xwnd;
lglw_bool_t mapped;
int32_t swap_interval;
} win;

GLXContext ctx;

struct {
GLXContext ctx;
GLXDrawable drw;
} prev;

struct {
@@ -142,27 +160,56 @@ static void loc_enable_dropfiles (lglw_int_t *lglw, lglw_bool_t _bEnable);
static lglw_int_t *khook_lglw = NULL; // currently key-hooked lglw instance (one at a time)


// TODO: remove and/or improve debug logging for a debug build
// ---------------------------------------------------------------------------- lglw_log
static FILE *logfile;

void lglw_log(const char *logData, ...) {
fprintf(logfile, logData);
fflush(logfile);
}


// TODO: remove, or maybe not in some specific use cases
// ---------------------------------------------------------------------------- xerror_log
static int xerror_handler(Display *display, XErrorEvent *error) {
char error_text[1024];
XGetErrorText(display, error->error_code, error_text, 1024);
lglw_log("XERROR (%d): %s, %d, %d\n", error->error_code, error_text, error->request_code, error->minor_code);
return 0;
}


// ---------------------------------------------------------------------------- lglw_init
lglw_t lglw_init(int32_t _w, int32_t _h) {
lglw_int_t *lglw = malloc(sizeof(lglw_int_t));

// TODO: remove/improve
logfile = fopen("/home/cameron/src/VeeSeeVSTRack/other/log.txt", "w");
XSetErrorHandler(xerror_handler);

if(NULL != lglw)
{
memset(lglw, 0, sizeof(lglw_int_t));

lglw_log("lglw:lglw_init: 1\n");
if(_w <= 16)
_w = LGLW_DEFAULT_HIDDEN_W;

if(_h <= 16)
_h = LGLW_DEFAULT_HIDDEN_H;

lglw_log("lglw:lglw_init: 2\n");
if(!loc_create_hidden_window(lglw, _w, _h))
{
free(lglw);
lglw = NULL;
}
lglw_log("lglw:lglw_init: 3\n");
}

lglw_log("lglw:lglw_init: EXIT\n");

return lglw;
}

@@ -173,8 +220,13 @@ void lglw_exit(lglw_t _lglw) {

if(NULL != lglw)
{
lglw_log("lglw:lglw_exit: 1\n");

loc_destroy_hidden_window(lglw);

lglw_log("lglw:lglw_exit: 2\n");

fclose(logfile);
free(lglw);
}
}
@@ -186,6 +238,7 @@ void lglw_userdata_set(lglw_t _lglw, void *_userData) {

if(NULL != lglw)
{
lglw_log("lglw:lglw_userdata_set: 1\n");
lglw->user_data = _userData;
}
}
@@ -196,6 +249,7 @@ void *lglw_userdata_get(lglw_t _lglw) {

if(NULL != lglw)
{
lglw_log("lglw:lglw_userdata_get: 1\n");
return lglw->user_data;
}

@@ -206,40 +260,232 @@ void *lglw_userdata_get(lglw_t _lglw) {
// ---------------------------------------------------------------------------- loc_create_hidden_window
static lglw_bool_t loc_create_hidden_window(lglw_int_t *lglw, int32_t _w, int32_t _h) {

// (todo) implement me
// TODO: compare to 'WindowClass' from Windows implementation

lglw_log("lglw:loc_create_hidden_window: 1\n");
XSetWindowAttributes swa;
int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 24, None };
int screen;

lglw_log("lglw:loc_create_hidden_window: 2\n");
lglw->xdsp = XOpenDisplay(NULL);
screen = DefaultScreen(lglw->xdsp);

lglw_log("lglw:loc_create_hidden_window: 3\n");
lglw->vi = glXChooseVisual(lglw->xdsp, screen, attrib);

lglw_log("lglw:loc_create_hidden_window: 4\n");
if(NULL == lglw->vi)
{
lglw_log("[---] lglw: failed to find GLX Visual for hidden window\n");
return LGLW_FALSE;
}

lglw_log("lglw:loc_create_hidden_window: 5\n");
lglw->ctx = glXCreateContext(lglw->xdsp, lglw->vi, None, True);

lglw_log("lglw:loc_create_hidden_window: 6\n");
if(NULL == lglw->ctx)
{
lglw_log("[---] lglw: failed to create GLX Context for hidden window\n");
return LGLW_FALSE;
}

lglw_log("lglw:loc_create_hidden_window: 7\n");
lglw->cmap = XCreateColormap(lglw->xdsp, RootWindow(lglw->xdsp, lglw->vi->screen),
lglw->vi->visual, AllocNone);

lglw_log("lglw:loc_create_hidden_window: 8\n");
swa.border_pixel = 0;
swa.colormap = lglw->cmap;
lglw->hidden.xwnd = XCreateWindow(lglw->xdsp, DefaultRootWindow(lglw->xdsp),
0, 0, LGLW_DEFAULT_HIDDEN_W, LGLW_DEFAULT_HIDDEN_H, 0, CopyFromParent, InputOutput,
lglw->vi->visual, CWBorderPixel | CWColormap, &swa);

lglw_log("lglw:loc_create_hidden_window: 9\n");
XSetStandardProperties(lglw->xdsp, lglw->hidden.xwnd, "LGLW_hidden", "LGLW_hidden", None, NULL, 0, NULL);
XSync(lglw->xdsp, False);

lglw_log("lglw:loc_create_hidden_window: EXIT\n");
lglw->hidden.size.x = _w;
lglw->hidden.size.y = _h;

return LGLW_FALSE;
return LGLW_TRUE;
}


// ---------------------------------------------------------------------------- loc_destroy_hidden_window
static void loc_destroy_hidden_window(lglw_int_t *lglw) {
// (todo) implement me
lglw_log("lglw:loc_destroy_hidden_window: 1\n");
if(NULL != lglw->xdsp && NULL != lglw->ctx)
{
glXMakeCurrent(lglw->xdsp, None, NULL);
glXDestroyContext(lglw->xdsp, lglw->ctx);
}
lglw_log("lglw:loc_destroy_hidden_window: 2\n");
if(NULL != lglw->xdsp && 0 != lglw->hidden.xwnd) XDestroyWindow(lglw->xdsp, lglw->hidden.xwnd);
lglw_log("lglw:loc_destroy_hidden_window: 3\n");
if(NULL != lglw->xdsp && 0 != lglw->cmap) XFreeColormap(lglw->xdsp, lglw->cmap);
lglw_log("lglw:loc_destroy_hidden_window: 4\n");
if(NULL != lglw->vi) XFree(lglw->vi);

lglw_log("lglw:loc_destroy_hidden_window: 5\n");
XSync(lglw->xdsp, False);
if(NULL != lglw->xdsp) XCloseDisplay(lglw->xdsp);
}


// ---------------------------------------------------------------------------- loc_setEventProc
// https://www.kvraudio.com/forum/viewtopic.php?t=387924
// https://github.com/Ardour/ardour/blob/master/gtk2_ardour/linux_vst_gui_support.cc
// https://discourse.ardour.org/t/overtonedsp-plugins/90115/22
// https://github.com/amsynth/amsynth/blob/4a87798e650c6d71d70274a961c9b8d98fc6da7e/src/amsynth_vst.cpp
// https://github.com/rsenn/eXT2/blob/7f00a09561ded8175ffed2f4912dad74e466a1c7/vstplugins/vstgui/vstgui.cpp
// https://github.com/COx2/DistortionFilter/blob/c6a34fb56b503a6e95bf0975e00f438bbf4ff52a/juce/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp

// Very simple function to test _XEventProc is properly called
void loc_eventProc(void *xevent) {
// lglw_log("XEventProc");
printf("XEventProc\n");
}

// Pulled from the Renoise 64-bit callback example
// Unsure what data was supposed to be, but swapping it to a function name did not work
// This does nothing, no event proc found
// TODO: 32-bit support
// void loc_setEventProc (Display *display, Window window) {
// size_t data = (size_t)loc_eventProc;
// long temp[2];

// // Split the 64 bit pointer into a little-endian long array
// temp[0] = (long)(data & 0xffffffffUL);
// temp[1] = (long)(data >> 32L);

// Atom atom = XInternAtom(display, "_XEventProc", False);
// XChangeProperty(display, window, atom, atom, 32,
// PropModeReplace, (unsigned char*)temp, 2);
// }

// Pulled from the eXT2 example
// TODO: 32-bit support
void loc_setEventProc (Display *display, Window window) {
void* data = (void*)&loc_eventProc; // swapped the function name here

Atom atom = XInternAtom(display, "_XEventProc", False);
XChangeProperty(display, window, atom, atom, 32,
PropModeReplace, (unsigned char*)&data, 1); // 1 instead of 2 will crash Ardour, 2 will not do anything
}

// Pulled from the amsynth example
// Simply swapped out the function names, crashes Ardour in the same was as the others
// void loc_setEventProc (Display *display, Window window) {
// #ifdef BUILD_64
// //
// // JUCE calls XGetWindowProperty with long_length = 1 which means it only fetches the lower 32 bits of the address.
// // Therefore we need to ensure we return an address in the lower 32-bits of address space.
// //

// // based on mach_override
// static const unsigned char kJumpInstructions[] = {
// 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00
// };
// static const int kJumpAddress = 6;

// static char *ptr;
// if (!ptr) {
// ptr = (char *)mmap(0,
// PAGE_SIZE,
// PROT_READ | PROT_WRITE | PROT_EXEC,
// MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT,
// 0, 0);
// if (ptr == MAP_FAILED) {
// perror("mmap");
// ptr = 0;
// return;
// } else {
// memcpy(ptr, kJumpInstructions, sizeof(kJumpInstructions));
// *((uint64_t *)(ptr + kJumpAddress)) = (uint64_t)(&loc_eventProc);
// msync(ptr, sizeof(kJumpInstructions), MS_INVALIDATE);
// }
// }

// long temp[2] = {(long)ptr, 0};
// Atom atom = XInternAtom(display, "_XEventProc", False);
// XChangeProperty(display, window, atom, atom, 32, PropModeReplace, (unsigned char *)temp, 2);
// #else
// long temp[1] = {(long)(void *)(&loc_eventProc)};
// Atom atom = XInternAtom(display, "_XEventProc", False);
// XChangeProperty(display, window, atom, atom, 32, PropModeReplace, (unsigned char *)temp, 1);
// #endif
// }


// ---------------------------------------------------------------------------- lglw_window_open
lglw_bool_t lglw_window_open (lglw_t _lglw, void *_parentHWNDOrNull, int32_t _x, int32_t _y, int32_t _w, int32_t _h) {
lglw_bool_t r = LGLW_FALSE;
LGLW(_lglw);

// (todo) implement me

if(NULL != lglw)
{
lglw_log("lglw:lglw_window_open: 1, %p, %i\n", (Window)_parentHWNDOrNull, (Window)_parentHWNDOrNull);
lglw->parent_xwnd = (0 == _parentHWNDOrNull) ? DefaultRootWindow(lglw->xdsp) : (Window)_parentHWNDOrNull;

lglw_log("lglw:lglw_window_open: 2\n");
if(_w <= 16)
_w = lglw->hidden.size.x;

lglw_log("lglw:lglw_window_open: 3\n");
if(_h <= 16)
_h = lglw->hidden.size.y;

// TODO: compare to 'WindowClass' from Windows implementation

lglw_log("lglw:lglw_window_open: 4\n");
XSetWindowAttributes swa;
XEvent event;
XSync(lglw->xdsp, False);

lglw_log("lglw:lglw_window_open: 5\n");
swa.border_pixel = 0;
swa.colormap = lglw->cmap;
swa.event_mask = EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask;
lglw->win.xwnd = XCreateWindow(lglw->xdsp, DefaultRootWindow(lglw->xdsp),
0, 0, _w, _h, 0, CopyFromParent, InputOutput,
lglw->vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa);

lglw_log("lglw:lglw_window_open: 6\n");
XSetStandardProperties(lglw->xdsp, lglw->win.xwnd, "LGLW", "LGLW", None, NULL, 0, NULL);

// Setup the event proc now, on the parent window as well just for the debug host
// It was simpler to do this than check in the debug host for the reparent event
lglw_log("lglw:lglw_window_open: 7\n");
loc_setEventProc(lglw->xdsp, lglw->win.xwnd);
loc_setEventProc(lglw->xdsp, lglw->parent_xwnd);

// Some hosts only check and store the callback when the Window is reparented
// Since creating the Window with a Parent may or may not do that, but the callback is not set,
// ... it's created as a root window, the callback is set, and then it's reparented
if (0 != _parentHWNDOrNull)
{
lglw_log("lglw:lglw_window_open: 8\n");
XReparentWindow(lglw->xdsp, lglw->win.xwnd, lglw->parent_xwnd, 0, 0);
}

lglw_log("lglw:lglw_window_open: 9\n");
XMapRaised(lglw->xdsp, lglw->win.xwnd);
XSync(lglw->xdsp, False);
lglw->win.mapped = LGLW_TRUE;

lglw_log("lglw:lglw_window_open: 10\n");
lglw->win.size.x = _w;
lglw->win.size.y = _h;

lglw_log("lglw:lglw_window_open: 11\n");
loc_enable_dropfiles(lglw, (NULL != lglw->dropfiles.cbk));

lglw_log("lglw:lglw_window_open: EXIT\n");
}
return r;
}
@@ -250,10 +496,56 @@ lglw_bool_t lglw_window_resize (lglw_t _lglw, int32_t _w, int32_t _h) {
lglw_bool_t r = LGLW_FALSE;
LGLW(_lglw);

// (todo) implement me

if(NULL != lglw)
{
if(0 != lglw->win.xwnd)
{
lglw_log("lglw:lglw_window_resize: 1\n");
r = LGLW_TRUE;

lglw_log("lglw:lglw_window_resize: 2\n");
XResizeWindow(lglw->xdsp, lglw->win.xwnd, _w, _h);
XRaiseWindow(lglw->xdsp, lglw->win.xwnd);

lglw_log("lglw:lglw_window_resize: 3\n");
int deltaW = _w - lglw->win.size.x;
int deltaH = _h - lglw->win.size.y;

lglw_log("lglw:lglw_window_resize: 4\n");
lglw->win.size.x = _w;
lglw->win.size.y = _h;

lglw_log("lglw:lglw_window_resize: 5\n");
Window root, parent, *children = NULL;
unsigned int num_children;

lglw_log("lglw:lglw_window_resize: 6\n");
if(!XQueryTree(lglw->xdsp, lglw->win.xwnd, &root, &parent, &children, &num_children))
return r;

lglw_log("lglw:lglw_window_resize: 7\n");
if(children)
XFree((char *)children);

lglw_log("lglw:lglw_window_resize: 8\n");
// Resize parent window (if any)
if(0 != parent)
{
lglw_log("lglw:lglw_window_resize: 8.1\n");
int x, y;
unsigned int width, height;
unsigned int border_width;
unsigned int depth;

lglw_log("lglw:lglw_window_resize: 8.2\n");
if(!XGetGeometry(lglw->xdsp, lglw->win.xwnd, &root, &x, &y, &width, &height, &border_width, &depth))
return r;

lglw_log("lglw:lglw_window_resize: 8.3\n");
XResizeWindow(lglw->xdsp, parent, width + deltaW, height + deltaH);
}
lglw_log("lglw:lglw_window_resize: EXIT\n");
}
}

return r;
@@ -264,17 +556,27 @@ lglw_bool_t lglw_window_resize (lglw_t _lglw, int32_t _w, int32_t _h) {
void lglw_window_close (lglw_t _lglw) {
LGLW(_lglw);

// (todo) implement me

if(NULL != lglw)
{
// if(NULL != lglw->win.hwnd)
if(0 != lglw->win.xwnd)
{
lglw_log("lglw:lglw_window_close: 1\n");
lglw_timer_stop(_lglw);

lglw_log("lglw:lglw_window_close: 2\n");
loc_key_unhook(lglw);

lglw_log("lglw:lglw_window_close: 3\n");
glXMakeCurrent(lglw->xdsp, None, NULL);

lglw_log("lglw:lglw_window_close: 4\n");
XDestroyWindow(lglw->xdsp, lglw->win.xwnd);
XSync(lglw->xdsp, False);
lglw->win.xwnd = 0;
lglw->win.mapped = LGLW_FALSE;
}
}
lglw_log("lglw:lglw_window_close: EXIT\n");
}


@@ -282,11 +584,14 @@ void lglw_window_close (lglw_t _lglw) {
void lglw_window_show(lglw_t _lglw) {
LGLW(_lglw);

// (todo) implement me

if(NULL != lglw)
{
lglw_log("lglw:lglw_window_show: 1\n");
XMapRaised(lglw->xdsp, lglw->win.xwnd);

lglw->win.mapped = LGLW_TRUE;
}
lglw_log("lglw:lglw_window_show: EXIT\n");
}


@@ -294,11 +599,14 @@ void lglw_window_show(lglw_t _lglw) {
void lglw_window_hide(lglw_t _lglw) {
LGLW(_lglw);

// (todo) implement me

if(NULL != lglw)
{
lglw_log("lglw:lglw_window_hide: 1\n");
XUnmapWindow(lglw->xdsp, lglw->win.xwnd);

lglw->win.mapped = LGLW_FALSE;
}
lglw_log("lglw:lglw_window_hide: EXIT\n");
}


@@ -307,12 +615,14 @@ lglw_bool_t lglw_window_is_visible(lglw_t _lglw) {
lglw_bool_t r = LGLW_FALSE;
LGLW(_lglw);

// (todo) implement me

if(NULL != lglw)
// lglw_log("lglw:lglw_window_is_visible: 1\n");
if(NULL != lglw && 0 != lglw->win.xwnd)
{
// lglw_log("lglw:lglw_window_is_visible: 2\n");
r = lglw->win.mapped;
}

// lglw_log("lglw:lglw_window_is_visible: EXIT\n");
return r;
}

@@ -321,11 +631,19 @@ lglw_bool_t lglw_window_is_visible(lglw_t _lglw) {
void lglw_window_size_get(lglw_t _lglw, int32_t *_retX, int32_t *_retY) {
LGLW(_lglw);

// (todo) implement me

lglw_log("lglw:lglw_window_size_get: 1\n");
if(NULL != lglw)
{
if(0 != lglw->win.xwnd)
{
if(NULL != _retX)
*_retX = lglw->win.size.x;

if(NULL != _retY)
*_retY = lglw->win.size.y;
}
}
lglw_log("lglw:lglw_window_size_get: EXIT\n");
}


@@ -337,6 +655,13 @@ void lglw_redraw(lglw_t _lglw) {

if(NULL != lglw)
{
if(0 != lglw->win.xwnd)
{
// TODO Event Loop
lglw_log("lglw:lglw_redraw: 1\n");
XClearArea(lglw->xdsp, lglw->win.xwnd, 0, 0, 1, 1, True); // clear tiny area for exposing
XFlush(lglw->xdsp);
}
}
}

@@ -355,11 +680,18 @@ void lglw_redraw_callback_set(lglw_t _lglw, lglw_redraw_fxn_t _cbk) {
// ---------------------------------------------------------------------------- lglw_glcontext_push
void lglw_glcontext_push(lglw_t _lglw) {
LGLW(_lglw);
// (todo) implement me

if(NULL != lglw)
{
lglw->prev.drw = glXGetCurrentDrawable();
lglw->prev.ctx = glXGetCurrentContext();

// lglw_log("lglw:lglw_glcontext_push: win.xwnd=%p hidden.xwnd=%p ctx=%p\n",
// lglw->win.xwnd, lglw->hidden.xwnd, lglw->ctx);
if(!glXMakeCurrent(lglw->xdsp, (0 == lglw->win.xwnd) ? lglw->hidden.xwnd : lglw->win.xwnd, lglw->ctx))
{
lglw_log("[---] lglw_glcontext_push: glXMakeCurrent() failed. win.xwnd=%p hidden.xwnd=%p ctx=%p glGetError()=%d\n", lglw->win.xwnd, lglw->hidden.xwnd, lglw->ctx, glGetError());
}
}
}

@@ -367,11 +699,15 @@ void lglw_glcontext_push(lglw_t _lglw) {
// ---------------------------------------------------------------------------- lglw_glcontext_pop
void lglw_glcontext_pop(lglw_t _lglw) {
LGLW(_lglw);
// (todo) implement me

if(NULL != lglw)
{
// lglw_log("lglw:lglw_glcontext_pop: prev.drw=%p prev.ctx=%p\n",
// lglw->prev.drw, lglw->prev.ctx);
if(!glXMakeCurrent(lglw->xdsp, lglw->prev.drw, lglw->prev.ctx))
{
lglw_log("[---] lglw_glcontext_pop: glXMakeCurrent() failed. prev.drw=%p ctx=%p glGetError()=%d\n", lglw->prev.drw, lglw->prev.ctx, glGetError());
}
}
}

@@ -380,22 +716,33 @@ void lglw_glcontext_pop(lglw_t _lglw) {
void lglw_swap_buffers(lglw_t _lglw) {
LGLW(_lglw);

// (todo) implement me

if(NULL != lglw)
{
if(0 != lglw->win.xwnd)
{
// lglw_log("lglw:lglw_swap_buffers: 1\n");
glXSwapBuffers(lglw->xdsp, lglw->win.xwnd);
}
}
}


// ---------------------------------------------------------------------------- lglw_swap_interval_set
typedef void (APIENTRY *PFNWGLEXTSWAPINTERVALPROC) (int);
void lglw_swap_interval_set(lglw_t _lglw, int32_t _ival) {
LGLW(_lglw);

// (todo) implement me

if(NULL != lglw)
{
lglw_log("lglw:lglw_swap_interval_set: 1\n");
PFNWGLEXTSWAPINTERVALPROC glXSwapIntervalEXT;
glXSwapIntervalEXT = (PFNWGLEXTSWAPINTERVALPROC) glXGetProcAddress("glXSwapIntervalEXT");
if(NULL != glXSwapIntervalEXT)
{
lglw_log("lglw:lglw_swap_interval_set: 2\n");
glXSwapIntervalEXT(_ival);
lglw->win.swap_interval = _ival;
}
}
}

@@ -444,7 +791,7 @@ static void loc_handle_mouseleave(lglw_int_t *lglw) {
lglw->focus.cbk(lglw, lglw->focus.state, LGLW_FOCUS_MOUSE);
}

Dprintf("xxx lglw:loc_handle_mouseleave: LEAVE\n");
lglw_log("xxx lglw:loc_handle_mouseleave: LEAVE\n");
}


@@ -460,7 +807,7 @@ static void loc_handle_mouseenter(lglw_int_t *lglw) {
lglw->focus.cbk(lglw, lglw->focus.state, LGLW_FOCUS_MOUSE);
}

Dprintf("xxx lglw:loc_handle_mouseenter: LEAVE\n");
lglw_log("xxx lglw:loc_handle_mouseenter: LEAVE\n");
}




+ 1
- 1
other/vst2_debug_host/makefile.linux View File

@@ -6,7 +6,7 @@ include ../../dep/yac/install_linux.mk

.PHONY: bin
bin: vst2_debug_host.o
$(CPP) -o vst2_debug_host vst2_debug_host.o -ldl
$(CPP) -o vst2_debug_host vst2_debug_host.o -ldl -L/usr/lib -lpthread -lX11

.PHONY: clean
clean:


+ 121
- 2
other/vst2_debug_host/vst2_debug_host.cpp View File

@@ -2,7 +2,8 @@
//

#define DLL_PATH "../../vst2_bin/veeseevstrack_effect.dll"
#define SO_PATH "../../vst2_bin/veeseevstrack_effect.so"
// #define SO_PATH "../../vst2_bin/veeseevstrack_effect.so"
#define SO_PATH "../vst2_lglw_debug_plugin/debug_lglw.so"


#include <yac.h>
@@ -12,6 +13,11 @@
#include <windows.h>
#else
#include <dlfcn.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#endif

#include <aeffect.h>
@@ -19,6 +25,49 @@

typedef AEffect* (*PluginEntryProc) (audioMasterCallback audioMaster);

#ifndef YAC_WIN32
// https://github.com/Ardour/ardour/blob/master/gtk2_ardour/linux_vst_gui_support.cc
long getXWindowProperty(Display* display, Window window, Atom atom)
{
long result = 0;
int userSize;
unsigned long bytes;
unsigned long userCount;
unsigned char *data;
Atom userType;
// LXVST_xerror = false;

/*Use our own Xerror handler while we're in here - in an
attempt to stop the brain dead default Xerror behaviour of
qutting the entire application because of e.g. an invalid
window ID*/

// XErrorHandler olderrorhandler = XSetErrorHandler(TempErrorHandler);

XGetWindowProperty(display,
window,
atom,
0,
2,
false,
AnyPropertyType,
&userType,
&userSize,
&userCount,
&bytes,
&data);

if(userCount == 1)
result = *(long*)data;

// XSetErrorHandler(olderrorhandler);

/*Hopefully this will return zero if the property is not set*/

return result;
}
#endif


static VstIntPtr VSTCALLBACK HostCallback(AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt) {
static VstInt32 lastOpcode = -1;
@@ -48,6 +97,15 @@ void open_and_close(void) {
}
#endif

#ifndef YAC_WIN32
Display *d;
Window w;
int s;

d = XOpenDisplay(NULL);
s = DefaultScreen(d);
#endif

for(int i = 0; i < 48; i++)
{
inputBuffers[i] = new float[4096];
@@ -79,18 +137,75 @@ void open_and_close(void) {

if(NULL != effect)
{

#ifndef YAC_WIN32
w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 100, 100, 1,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w, ExposureMask | KeyPressMask);
XMapRaised(d, w);
XFlush(d);
#endif

printf("xxx calling effect->dispatcher<effOpen>\n");
effect->dispatcher(effect, effOpen, 0, 0, NULL, 0.0f);
printf("xxx effect->dispatcher<effOpen> returned\n");
#ifdef YAC_WIN32
VstIntPtr ip = effect->dispatcher(effect, effEditOpen, 0, 0, NULL/*hWnd*/, 0.0f);
#else
VstIntPtr ip = effect->dispatcher(effect, effEditOpen, 0, 0, (void*)(w)/*hWnd*/, 0.0f);
#endif
(void)ip;
sleep(2);

#ifndef YAC_WIN32
long result = getXWindowProperty(d, w, XInternAtom(d, "_XEventProc", false));
if(result == 0)
{
printf("xxx no XEventProc found\n");
}
else
{
printf("xxx XEventProc found... calling\n");
void (* eventProc) (void * event);
eventProc = (void (*) (void* event))result;
eventProc(NULL);
}
#endif

printf("xxx calling effect->dispatcher<effEditIdle>\n");
effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
sleep(1);
printf("xxx calling effect->dispatcher<effEditIdle>\n");
effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
sleep(1);
printf("xxx calling effect->dispatcher<effEditClose>\n");
effect->dispatcher(effect, effEditClose, 0, 0, NULL, 0.0f);
sleep(1);
printf("xxx calling effect->dispatcher<effEditOpen> again\n");
#ifdef YAC_WIN32
effect->dispatcher(effect, effEditOpen, 0, 0, NULL/*hWnd*/, 0.0f);
#else
effect->dispatcher(effect, effEditOpen, 0, 0, (void*)(w)/*hWnd*/, 0.0f);
#endif
sleep(1);
printf("xxx calling effect->dispatcher<effEditIdle>\n");
effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
sleep(1);
printf("xxx call processreplacing\n");
for(int i = 0; i < 1024; i++)
{
effect->processReplacing(effect, inputBuffers, outputBuffers, (VstInt32)64);
}
printf("xxx calling effect->dispatcher<effEditClose>\n");
effect->dispatcher(effect, effEditClose, 0, 0, NULL, 0.0f);
sleep(1);
printf("xxx calling effect->dispatcher<effClose>\n");
effect->dispatcher(effect, effClose, 0, 0, NULL, 0.0f);
sleep(1);

#ifndef YAC_WIN32
XDestroyWindow(d, w);
#endif
}
}
else
@@ -110,10 +225,14 @@ void open_and_close(void) {
delete [] inputBuffers[i];
delete [] outputBuffers[i];
}

#ifndef YAC_WIN32
XCloseDisplay(d);
#endif
}

int main() {
for(;;)
for(int i = 0; i < 5; i++)
{
open_and_close();
}


+ 4
- 0
other/vst2_lglw_debug_plugin/.gitignore View File

@@ -0,0 +1,4 @@
.DS_Store
M3dB/.idea
vst2.x/aeffect.h
vst2.x/aeffectx.h

+ 266
- 0
other/vst2_lglw_debug_plugin/M3dB.xcodeproj/project.pbxproj View File

@@ -0,0 +1,266 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {

/* Begin PBXBuildFile section */
BD2A1F5751BB6465EFEB5889 /* plugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BD2A144C3B32EFA5180A38F5 /* plugin.cpp */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
BD2A1226DD4B6ED23F230900 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.info; path = Info.plist; sourceTree = "<group>"; };
BD2A144C3B32EFA5180A38F5 /* plugin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = plugin.cpp; sourceTree = "<group>"; };
BD2A17C571405D51496892C4 /* M3dB.___VARIABLE_bundleExtension___ */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "M3dB.___VARIABLE_bundleExtension___"; sourceTree = BUILT_PRODUCTS_DIR; };
BD2A18D6CA1C93179E40396A /* aeffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = aeffect.h; path = ../vst2.x/aeffect.h; sourceTree = "<group>"; };
BD2A1CFE51F03D1B40DA1230 /* aeffectx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = aeffectx.h; path = ../vst2.x/aeffectx.h; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
BD2A17410135F1BFA2BB6503 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
BD2A15554318E7C2EF2CD5DC /* Products */ = {
isa = PBXGroup;
children = (
BD2A17C571405D51496892C4 /* M3dB.___VARIABLE_bundleExtension___ */,
);
name = Products;
sourceTree = "<group>";
};
BD2A1DCFA27E77A6603B70A2 = {
isa = PBXGroup;
children = (
BD2A15554318E7C2EF2CD5DC /* Products */,
BD2A1F10D41E35E7FCDFA898 /* M3dB */,
BD2A144C3B32EFA5180A38F5 /* plugin.cpp */,
BD2A18D6CA1C93179E40396A /* aeffect.h */,
BD2A1CFE51F03D1B40DA1230 /* aeffectx.h */,
);
sourceTree = "<group>";
};
BD2A1F10D41E35E7FCDFA898 /* M3dB */ = {
isa = PBXGroup;
children = (
BD2A1226DD4B6ED23F230900 /* Info.plist */,
);
path = M3dB;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
BD2A186B82B2C6E8A0E9022C /* M3dB */ = {
isa = PBXNativeTarget;
buildConfigurationList = BD2A12A4CFEA12B6C7A8873E /* Build configuration list for PBXNativeTarget "M3dB" */;
buildPhases = (
BD2A15C927C3AD450E2DD52C /* Sources */,
BD2A17410135F1BFA2BB6503 /* Frameworks */,
BD2A175E365F9ED8C1C35C6F /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = M3dB;
productName = M3dB;
productReference = BD2A17C571405D51496892C4 /* M3dB.___VARIABLE_bundleExtension___ */;
productType = "com.apple.product-type.bundle";
};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
BD2A116B4EC711555868B9BA /* Project object */ = {
isa = PBXProject;
attributes = {
ORGANIZATIONNAME = pongasoft;
};
buildConfigurationList = BD2A1B7627DAA8FF541E84EC /* Build configuration list for PBXProject "M3dB" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = BD2A1DCFA27E77A6603B70A2;
productRefGroup = BD2A15554318E7C2EF2CD5DC /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
BD2A186B82B2C6E8A0E9022C /* M3dB */,
);
};
/* End PBXProject section */

/* Begin PBXResourcesBuildPhase section */
BD2A175E365F9ED8C1C35C6F /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
BD2A15C927C3AD450E2DD52C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BD2A1F5751BB6465EFEB5889 /* plugin.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */

/* Begin XCBuildConfiguration section */
BD2A1223BF2A633FEE5D6099 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = M3dB/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
PRODUCT_BUNDLE_IDENTIFIER = org.pongasoft.vst24.M3dB;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
WRAPPER_EXTENSION = vst;
};
name = Debug;
};
BD2A17437E006499CC8685D1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
BD2A186609800B3BD0ECFF98 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
DEPLOYMENT_POSTPROCESSING = YES;
INFOPLIST_FILE = M3dB/Info.plist;
INSTALL_PATH = "$(HOME)/Library/Audio/Plug-Ins/VST";
PRODUCT_BUNDLE_IDENTIFIER = org.pongasoft.vst24.M3dB;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = NO;
WRAPPER_EXTENSION = vst;
};
name = Release;
};
BD2A1D1EC28D17DC43ACBA09 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEPLOYMENT_LOCATION = NO;
DEPLOYMENT_POSTPROCESSING = NO;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INSTALL_PATH = "";
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
};
name = Release;
};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
BD2A12A4CFEA12B6C7A8873E /* Build configuration list for PBXNativeTarget "M3dB" */ = {
isa = XCConfigurationList;
buildConfigurations = (
BD2A1223BF2A633FEE5D6099 /* Debug */,
BD2A186609800B3BD0ECFF98 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
BD2A1B7627DAA8FF541E84EC /* Build configuration list for PBXProject "M3dB" */ = {
isa = XCConfigurationList;
buildConfigurations = (
BD2A17437E006499CC8685D1 /* Debug */,
BD2A1D1EC28D17DC43ACBA09 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = BD2A116B4EC711555868B9BA /* Project object */;
}

+ 7
- 0
other/vst2_lglw_debug_plugin/M3dB.xcodeproj/project.xcworkspace/contents.xcworkspacedata View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

+ 5
- 0
other/vst2_lglw_debug_plugin/M3dB.xcodeproj/project.xcworkspace/xcuserdata/ypujante.xcuserdatad/xcschemes/xcschememanagement.plist View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict />
</plist>

+ 22
- 0
other/vst2_lglw_debug_plugin/M3dB.xcodeproj/xcuserdata/ypujante.xcuserdatad/xcschemes/M3dB - Debug.xcscheme View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
version = "1.3">
<BuildAction>
<BuildActionEntries>
<BuildActionEntry
buildForRunning = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BD2A186B82B2C6E8A0E9022C"
BuildableName = "M3dB.vst"
BlueprintName = "M3dB"
ReferencedContainer = "container:M3dB.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<LaunchAction
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug">
</LaunchAction>
</Scheme>

+ 22
- 0
other/vst2_lglw_debug_plugin/M3dB.xcodeproj/xcuserdata/ypujante.xcuserdatad/xcschemes/M3dB - Release.xcscheme View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
version = "1.3">
<BuildAction>
<BuildActionEntries>
<BuildActionEntry
buildForRunning = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BD2A186B82B2C6E8A0E9022C"
BuildableName = "M3dB.vst"
BlueprintName = "M3dB"
ReferencedContainer = "container:M3dB.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<LaunchAction
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release">
</LaunchAction>
</Scheme>

+ 19
- 0
other/vst2_lglw_debug_plugin/M3dB.xcodeproj/xcuserdata/ypujante.xcuserdatad/xcschemes/xcschememanagement.plist View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>M3dB - Debug.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>M3dB - Release.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
</dict>
</dict>
</plist>

+ 26
- 0
other/vst2_lglw_debug_plugin/M3dB/Info.plist View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2017 pongasoft. All rights reserved.</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

+ 19
- 0
other/vst2_lglw_debug_plugin/makefile.linux View File

@@ -0,0 +1,19 @@

include ../../dep/yac/install_linux.mk

.cpp.o:
$(CPP) $(CPPFLAGS) $(OPTFLAGS_PLUGIN) -I"$(VSVR_BASE_DIR)/dep/yac/" -I"$(VST2_SDK_DIR)" -I"$(VSVR_BASE_DIR)/dep/lglw/" -shared -fPIC -c "$<" -o"$@"

.PHONY: bin
bin: plugin.o
$(CPP) -shared -o debug_lglw.so -Wl,-soname,debug_lglw.so -mtls-dialect=gnu2 plugin.o "$(VSVR_BASE_DIR)/dep/lglw/lglw_linux.o" -ldl -lGL -L/usr/lib -lm -lpthread

.PHONY: clean
clean:
rm -f plugin plugin.o

.PHONY: all
all:
make -f makefile.linux clean
make -f makefile.linux bin
cp debug_lglw.so /home/cameron/.local/share/VST/

+ 458
- 0
other/vst2_lglw_debug_plugin/plugin.cpp View File

@@ -0,0 +1,458 @@


#include <aeffect.h>
#include <aeffectx.h>
#include <stdio.h>

#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#include <wingdi.h>
#define VST_EXPORT extern "C" __declspec(dllexport)
#else
#include <GL/gl.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#define VST_EXPORT extern
#endif

#include "lglw.h"

#define EDITWIN_X 20
#define EDITWIN_Y 20
#define EDITWIN_W 640
#define EDITWIN_H 480

/*
* I find the naming a bit confusing so I decided to use more meaningful names instead.
*/

/**
* The VSTHostCallback is a function pointer so that the plugin can communicate with the host (not used in this small example)
*/
typedef audioMasterCallback VSTHostCallback;

/**
* The VSTPlugin structure (AEffect) contains information about the plugin (like version, number of inputs, ...) and
* callbacks so that the host can call the plugin to do its work. The primary callback will be `processReplacing` for
* single precision (float) sample processing (or `processDoubleReplacing` for double precision (double)).
*/
typedef AEffect VSTPlugin;


// Since the host is expecting a very specific API we need to make sure it has C linkage (not C++)
extern "C" {

/*
* This is the main entry point to the VST plugin.
*
* The host (DAW like Maschine, Ableton Live, Reason, ...) will look for this function with this exact API.
*
* It is the equivalent to `int main(int argc, char *argv[])` for a C executable.
*
* @param vstHostCallback is a callback so that the plugin can communicate with the host (not used in this small example)
* @return a pointer to the AEffect structure
*/
VST_EXPORT VSTPlugin *VSTPluginMain(VSTHostCallback vstHostCallback);

// note this looks like this without the type aliases (and is obviously 100% equivalent)
// extern AEffect *VSTPluginMain(audioMasterCallback audioMaster);

}

/*
* Constant for the version of the plugin. For example 1100 for version 1.1.0.0
*/
const VstInt32 PLUGIN_VERSION = 1000;

// extern "C" LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

void loc_mouse_cbk(lglw_t _lglw, int32_t _x, int32_t _y, uint32_t _buttonState, uint32_t _changedButtonState) {
printf("xxx lglw_mouse_cbk: lglw=%p p=(%d; %d) bt=0x%08x changedBt=0x%08x\n", _lglw, _x, _y, _buttonState, _changedButtonState);

if(LGLW_IS_MOUSE_LBUTTON_DOWN())
{
// lglw_mouse_grab(_lglw, LGLW_MOUSE_GRAB_CAPTURE);
lglw_mouse_grab(_lglw, LGLW_MOUSE_GRAB_WARP);
}
else if(LGLW_IS_MOUSE_LBUTTON_UP())
{
lglw_mouse_ungrab(_lglw);
}
}

void loc_focus_cbk(lglw_t _lglw, uint32_t _focusState, uint32_t _changedFocusState) {
printf("xxx lglw_focus_cbk: lglw=%p focusState=0x%08x changedFocusState=0x%08x\n", _lglw, _focusState, _changedFocusState);
}

lglw_bool_t loc_keyboard_cbk(lglw_t _lglw, uint32_t _vkey, uint32_t _kmod, lglw_bool_t _bPressed) {
printf("xxx lglw_keyboard_cbk: lglw=%p vkey=0x%08x (\'%c\') kmod=0x%08x bPressed=%d\n", _lglw, _vkey, _vkey, _kmod, _bPressed);
return LGLW_FALSE;
}

void loc_timer_cbk(lglw_t _lglw) {
printf("xxx lglw_timer_cbk: tick\n");
}

/**
* Encapsulates the plugin as a C++ class. It will keep both the host callback and the structure required by the
* host (VSTPlugin). This class will be stored in the `VSTPlugin.object` field (circular reference) so that it can
* be accessed when the host calls the plugin back (for example in `processDoubleReplacing`).
*/
class VSTPluginWrapper
{
public:
ERect editor_rect;

lglw_t lglw;

float clear_color = 0.0f;

static VSTPluginWrapper *window_to_wrapper;

public:
VSTPluginWrapper(VSTHostCallback vstHostCallback,
VstInt32 vendorUniqueID,
VstInt32 vendorVersion,
VstInt32 numParams,
VstInt32 numPrograms,
VstInt32 numInputs,
VstInt32 numOutputs);

~VSTPluginWrapper();

inline VSTPlugin *getVSTPlugin()
{
return &_vstPlugin;
}

inline VstInt32 getNumInputs() const
{
return _vstPlugin.numInputs;
}

inline VstInt32 getNumOutputs() const
{
return _vstPlugin.numOutputs;
}

void openEditor(void *_hwnd) {
(void)lglw_window_open(lglw, _hwnd, 0/*x*/, 0/*y*/, EDITWIN_W, EDITWIN_H);

lglw_mouse_callback_set(lglw, &loc_mouse_cbk);
lglw_focus_callback_set(lglw, &loc_focus_cbk);
lglw_keyboard_callback_set(lglw, &loc_keyboard_cbk);
lglw_timer_callback_set(lglw, &loc_timer_cbk);

lglw_timer_start(lglw, 200);

window_to_wrapper = this;
}

void closeEditor(void) {
if(NULL != window_to_wrapper)
{
lglw_window_close(lglw);

window_to_wrapper = NULL;
}
}

static VSTPluginWrapper *FindWrapperByWindow(Window hwnd) {
return window_to_wrapper;
}

void redrawWindow(void) {
// Save host GL context
lglw_glcontext_push(lglw);

// Draw something
::glClearColor(0.0, 1.0, clear_color, 1.0);
clear_color += 0.05f;
if(clear_color >= 1.0f)
clear_color -= 1.0f;
::glClear(GL_COLOR_BUFFER_BIT);

::glFlush();
lglw_swap_buffers(lglw);

// Restore host GL context
lglw_glcontext_pop(lglw);
}

private:
// the host callback (a function pointer)
VSTHostCallback _vstHostCallback;

// the actual structure required by the host
VSTPlugin _vstPlugin;
};

VSTPluginWrapper *VSTPluginWrapper::window_to_wrapper = NULL;


/*******************************************
* Callbacks: Host -> Plugin
*
* Defined here because they are used in the rest of the code later
*/

/**
* This is the callback that will be called to process the samples in the case of single precision. This is where the
* meat of the logic happens!
*
* @param vstPlugin the object returned by VSTPluginMain
* @param inputs an array of array of input samples. You read from it. First dimension is for inputs, second dimension is for samples: inputs[numInputs][sampleFrames]
* @param outputs an array of array of output samples. You write to it. First dimension is for outputs, second dimension is for samples: outputs[numOuputs][sampleFrames]
* @param sampleFrames the number of samples (second dimension in both arrays)
*/
void VSTPluginProcessSamplesFloat32(VSTPlugin *vstPlugin, float **inputs, float **outputs, VstInt32 sampleFrames)
{
// we can get a hold to our C++ class since we stored it in the `object` field (see constructor)
VSTPluginWrapper *wrapper = static_cast<VSTPluginWrapper *>(vstPlugin->object);

// code speaks for itself: for each input (2 when stereo input), iterating over every sample and writing the
// result in the outputs array after multiplying by 0.5 (which result in a 3dB attenuation of the sound)
for(int i = 0; i < wrapper->getNumInputs(); i++)
{
auto inputSamples = inputs[i];
auto outputSamples = outputs[i];
for(int j = 0; j < sampleFrames; j++)
{
outputSamples[j] = inputSamples[j] * 0.5f;
}
}
}

/**
* This is the callback that will be called to process the samples in the case of double precision. This is where the
* meat of the logic happens!
*
* @param vstPlugin the object returned by VSTPluginMain
* @param inputs an array of array of input samples. You read from it. First dimension is for inputs, second dimension is for samples: inputs[numInputs][sampleFrames]
* @param outputs an array of array of output samples. You write to it. First dimension is for outputs, second dimension is for samples: outputs[numOuputs][sampleFrames]
* @param sampleFrames the number of samples (second dimension in both arrays)
*/
void VSTPluginProcessSamplesFloat64(VSTPlugin *vstPlugin, double **inputs, double **outputs, VstInt32 sampleFrames)
{
// we can get a hold to our C++ class since we stored it in the `object` field (see constructor)
VSTPluginWrapper *wrapper = static_cast<VSTPluginWrapper *>(vstPlugin->object);

// code speaks for itself: for each input (2 when stereo input), iterating over every sample and writing the
// result in the outputs array after multiplying by 0.5 (which result in a 3dB attenuation of the sound)
for(int i = 0; i < wrapper->getNumInputs(); i++)
{
auto inputSamples = inputs[i];
auto outputSamples = outputs[i];
for(int j = 0; j < sampleFrames; j++)
{
outputSamples[j] = inputSamples[j] * 0.5;
}
}
}

/**
* This is the plugin called by the host to communicate with the plugin, mainly to request information (like the
* vendor string, the plugin category...) or communicate state/changes (like open/close, frame rate...)
*
* @param vstPlugin the object returned by VSTPluginMain
* @param opCode defined in aeffect.h/AEffectOpcodes and which continues in aeffectx.h/AEffectXOpcodes for a grand
* total of 79 of them! Only a few of them are implemented in this small plugin.
* @param index depend on the opcode
* @param value depend on the opcode
* @param ptr depend on the opcode
* @param opt depend on the opcode
* @return depend on the opcode (0 is ok when you don't implement an opcode...)
*/
VstIntPtr VSTPluginDispatcher(VSTPlugin *vstPlugin, VstInt32 opCode, VstInt32 index, VstIntPtr value, void *ptr, float opt)
{
// printf("vstgltest: called VSTPluginDispatcher(%d)\n", opCode);

VstIntPtr r = 0;

// we can get a hold to our C++ class since we stored it in the `object` field (see constructor)
VSTPluginWrapper *wrapper = static_cast<VSTPluginWrapper *>(vstPlugin->object);
// see aeffect.h/AEffectOpcodes and aeffectx.h/AEffectXOpcodes for details on all of them
switch(opCode)
{
// request for the category of the plugin: in this case it is an effect since it is modifying the input (as opposed
// to generating sound)
case effGetPlugCategory:
return kPlugCategEffect;

// called by the host when the plugin was called... time to reclaim memory!
case effClose:
delete wrapper;
break;

case effGetEffectName:
::strncpy((char*)ptr, "VST GL Test", kVstMaxEffectNameLen);
r = 1;
break;

// request for the vendor string (usually used in the UI for plugin grouping)
case effGetVendorString:
strncpy(static_cast<char *>(ptr), "bsp", kVstMaxVendorStrLen);
r = 1;
break;

// request for the version
case effGetVendorVersion:
return PLUGIN_VERSION;

case effGetParamName:
strncpy(static_cast<char *>(ptr), "myparam", kVstMaxParamStrLen);
r = 1;
break;

case effEditIdle:
printf("xxx vstgltest: redraw window\n");
// (void)::RedrawWindow(wrapper->hwnd, NULL, NULL, RDW_INTERNALPAINT);
//(void)::UpdateWindow(wrapper->hwnd);
if(lglw_window_is_visible(wrapper->lglw))
{
wrapper->redrawWindow();
}
break;

case effEditGetRect:
// Query editor window geometry
// ptr: ERect* (on Windows)
if(NULL != ptr) // yeah, this should never be NULL
{
// ...
wrapper->editor_rect.left = EDITWIN_X;
wrapper->editor_rect.top = EDITWIN_Y;
wrapper->editor_rect.right = EDITWIN_X + EDITWIN_W;
wrapper->editor_rect.bottom = EDITWIN_Y + EDITWIN_H;
*(void**)ptr = (void*) &wrapper->editor_rect;
r = 1;
}
else
{
r = 0;
}
break;

#if 0
case effEditTop:
// deprecated in vst2.4
r = 0;
break;
#endif

case effEditOpen:
// Show editor window
// ptr: native window handle (hWnd on Windows)
wrapper->openEditor(ptr);
r = 1;
break;

case effEditClose:
// Hide editor window
wrapper->closeEditor();
r = 1;
break;

// ignoring all other opcodes
default:
// printf("Unknown opCode %d [ignored] \n", opCode);
break;
}

return r;
}

/**
* Used for parameter setting (not used by this plugin)
*/
void VSTPluginSetParameter(VSTPlugin *vstPlugin, VstInt32 index, float parameter)
{
printf("called VSTPluginSetParameter(%d, %f)\n", index, parameter);
// we can get a hold to our C++ class since we stored it in the `object` field (see constructor)
VSTPluginWrapper *wrapper = static_cast<VSTPluginWrapper *>(vstPlugin->object);
}

/**
* Used for parameter (not used by this plugin)
*/
float VSTPluginGetParameter(VSTPlugin *vstPlugin, VstInt32 index)
{
printf("called VSTPluginGetParameter(%d)\n", index);
// we can get a hold to our C++ class since we stored it in the `object` field (see constructor)
VSTPluginWrapper *wrapper = static_cast<VSTPluginWrapper *>(vstPlugin->object);
return 0;
}

/**
* Main constructor for our C++ class
*/
VSTPluginWrapper::VSTPluginWrapper(audioMasterCallback vstHostCallback,
VstInt32 vendorUniqueID,
VstInt32 vendorVersion,
VstInt32 numParams,
VstInt32 numPrograms,
VstInt32 numInputs,
VstInt32 numOutputs) :
_vstHostCallback(vstHostCallback)
{
// Make sure that the memory is properly initialized
memset(&_vstPlugin, 0, sizeof(_vstPlugin));

// this field must be set with this constant...
_vstPlugin.magic = kEffectMagic;

// storing this object into the VSTPlugin so that it can be retrieved when called back (see callbacks for use)
_vstPlugin.object = this;

// specifying that we handle both single and double precision (there are other flags see aeffect.h/VstAEffectFlags)
_vstPlugin.flags = effFlagsCanReplacing | effFlagsCanDoubleReplacing | effFlagsHasEditor;

// initializing the plugin with the various values
_vstPlugin.uniqueID = vendorUniqueID;
_vstPlugin.version = vendorVersion;
_vstPlugin.numParams = numParams;
_vstPlugin.numPrograms = numPrograms;
_vstPlugin.numInputs = numInputs;
_vstPlugin.numOutputs = numOutputs;

// setting the callbacks to the previously defined functions
_vstPlugin.dispatcher = VSTPluginDispatcher;
_vstPlugin.getParameter = VSTPluginGetParameter;
_vstPlugin.setParameter = VSTPluginSetParameter;
_vstPlugin.processReplacing = VSTPluginProcessSamplesFloat32;
_vstPlugin.processDoubleReplacing = VSTPluginProcessSamplesFloat64;

lglw = lglw_init(EDITWIN_W, EDITWIN_H);
}

/**
* Destructor called when the plugin is closed (see VSTPluginDispatcher with effClose opCode). In this very simply plugin
* there is nothing to do but in general the memory that gets allocated MUST be freed here otherwise there might be a
* memory leak which may end up slowing down and/or crashing the host
*/
VSTPluginWrapper::~VSTPluginWrapper() {
lglw_exit(lglw);
}

/**
* Implementation of the main entry point of the plugin
*/
VST_EXPORT VSTPlugin *VSTPluginMain(VSTHostCallback vstHostCallback)
{
printf("called VSTPluginMain... \n");

// simply create our plugin C++ class
VSTPluginWrapper *plugin =
new VSTPluginWrapper(vstHostCallback,
CCONST('u', 's', 'a', '§'), // registered with Steinberg (http://service.steinberg.de/databases/plugin.nsf/plugIn?openForm)
PLUGIN_VERSION, // version
2, // no params
0, // no programs
2, // 2 inputs
2); // 2 outputs

// return the plugin per the contract of the API
return plugin->getVSTPlugin();
}

+ 615
- 0
other/vst2_lglw_debug_plugin/plugin.cpp__DUAL_WIN_CONTEXT_OK View File

@@ -0,0 +1,615 @@


#include <aeffect.h>
#include <aeffectx.h>
#include <stdio.h>

#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#include <wingdi.h>
#define VST_EXPORT extern "C" __declspec(dllexport)
#else
#define VST_EXPORT extern
#endif

#include <GL/GL.h>

#define EDITWIN_X 20
#define EDITWIN_Y 20
#define EDITWIN_W 640
#define EDITWIN_H 480
#define EDITWIN_CLASS_NAME "VeeSeeVSTWindow"
#define EDITWIN_HIDDEN_CLASS_NAME "hidden_VeeSeeVSTWindow"

/*
* I find the naming a bit confusing so I decided to use more meaningful names instead.
*/

/**
* The VSTHostCallback is a function pointer so that the plugin can communicate with the host (not used in this small example)
*/
typedef audioMasterCallback VSTHostCallback;

/**
* The VSTPlugin structure (AEffect) contains information about the plugin (like version, number of inputs, ...) and
* callbacks so that the host can call the plugin to do its work. The primary callback will be `processReplacing` for
* single precision (float) sample processing (or `processDoubleReplacing` for double precision (double)).
*/
typedef AEffect VSTPlugin;


// Since the host is expecting a very specific API we need to make sure it has C linkage (not C++)
extern "C" {

/*
* This is the main entry point to the VST plugin.
*
* The host (DAW like Maschine, Ableton Live, Reason, ...) will look for this function with this exact API.
*
* It is the equivalent to `int main(int argc, char *argv[])` for a C executable.
*
* @param vstHostCallback is a callback so that the plugin can communicate with the host (not used in this small example)
* @return a pointer to the AEffect structure
*/
VST_EXPORT VSTPlugin *VSTPluginMain(VSTHostCallback vstHostCallback);

// note this looks like this without the type aliases (and is obviously 100% equivalent)
// extern AEffect *VSTPluginMain(audioMasterCallback audioMaster);

}

/*
* Constant for the version of the plugin. For example 1100 for version 1.1.0.0
*/
const VstInt32 PLUGIN_VERSION = 1000;

extern "C" LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

/**
* Encapsulates the plugin as a C++ class. It will keep both the host callback and the structure required by the
* host (VSTPlugin). This class will be stored in the `VSTPlugin.object` field (circular reference) so that it can
* be accessed when the host calls the plugin back (for example in `processDoubleReplacing`).
*/
class VSTPluginWrapper
{
public:
ERect editor_rect;
HWND parent_hwnd; // created by host

struct {
HWND hwnd;
HDC hdc;
} hidden;

struct {
HWND hwnd;
HDC hdc;
} editor;

HGLRC hglrc;

float clear_color = 0.0f;

static const char *registered_class_name;
static VSTPluginWrapper *window_to_wrapper;

public:
VSTPluginWrapper(VSTHostCallback vstHostCallback,
VstInt32 vendorUniqueID,
VstInt32 vendorVersion,
VstInt32 numParams,
VstInt32 numPrograms,
VstInt32 numInputs,
VstInt32 numOutputs);

~VSTPluginWrapper();

inline VSTPlugin *getVSTPlugin()
{
return &_vstPlugin;
}

inline VstInt32 getNumInputs() const
{
return _vstPlugin.numInputs;
}

inline VstInt32 getNumOutputs() const
{
return _vstPlugin.numOutputs;
}

void createHiddenWindow(void) {
WNDCLASS wc;
::ZeroMemory(&wc, sizeof(wc));
wc.style = CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.hInstance = ::GetModuleHandle(NULL);
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = EDITWIN_HIDDEN_CLASS_NAME;

if(!::RegisterClass(&wc))
{
// something went terribly wrong
printf("[---] vstgltest: failed to register hidden window class\n");
return;
}

DWORD dwExStyle = 0;
DWORD dwStyle = 0;

hidden.hwnd = ::CreateWindowEx(dwExStyle,
EDITWIN_HIDDEN_CLASS_NAME,
"Test",
dwStyle,
0/*xpos*/, 0/*ypos*/,
EDITWIN_W, EDITWIN_H,
NULL/*parentHWND*/,
NULL, // window menu
::GetModuleHandle(NULL),
NULL
);

PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //Flags
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
32, // Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, // Number of bits for the depthbuffer
8, // Number of bits for the stencilbuffer
0, // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};

hidden.hdc = ::GetDC(hidden.hwnd);
printf("xxx vstgltest: hidden hdc=%p\n", hidden.hdc);

int pfmt = ::ChoosePixelFormat(hidden.hdc, &pfd);
printf("xxx vstgltest: hidden pfmt=%d\n", pfmt);
::SetPixelFormat(hidden.hdc, pfmt, &pfd);

hglrc = ::wglCreateContext(hidden.hdc);
printf("xxx vstgltest: hidden hglrc=%p\n", hglrc);
}

void destroyHiddenWindow(void) {
if(NULL != hidden.hwnd)
{
::wglDeleteContext(hglrc);
::DestroyWindow(hidden.hwnd);

::UnregisterClass(EDITWIN_HIDDEN_CLASS_NAME, ::GetModuleHandle(NULL));
}
}

void openEditor(HWND _hwnd) {
parent_hwnd = _hwnd;

if(NULL == registered_class_name)
{
WNDCLASS wc;
::ZeroMemory(&wc, sizeof(wc));
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.hInstance = ::GetModuleHandle(NULL);
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = EDITWIN_CLASS_NAME;

if(!::RegisterClass(&wc))
{
// something went terribly wrong
printf("[---] vstgltest: failed to register window class\n");
return;
}

registered_class_name = EDITWIN_CLASS_NAME;
}

DWORD dwExStyle = 0;
DWORD dwStyle = WS_CHILD | WS_VISIBLE;

editor.hwnd = ::CreateWindowEx(dwExStyle,
EDITWIN_CLASS_NAME,
"Test",
dwStyle,
0/*xpos*/, 0/*ypos*/,
EDITWIN_W, EDITWIN_H,
parent_hwnd,
NULL, // window menu
::GetModuleHandle(NULL),
NULL
);

window_to_wrapper = this;

PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //Flags
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
32, // Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, // Number of bits for the depthbuffer
8, // Number of bits for the stencilbuffer
0, // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};

editor.hdc = ::GetDC(editor.hwnd);

int pfmt = ::ChoosePixelFormat(editor.hdc, &pfd);
printf("xxx vstgltest: editor pfmt=%d\n", pfmt);
::SetPixelFormat(editor.hdc, pfmt, &pfd);

// // hglrc = ::wglCreateContext(hdc);
}

void closeEditor(void) {
if(NULL != editor.hwnd)
{
::DestroyWindow(editor.hwnd);
editor.hwnd = NULL;

// (todo) unregister when last window is closed
::UnregisterClass(EDITWIN_CLASS_NAME, ::GetModuleHandle(NULL));
registered_class_name = NULL;

window_to_wrapper = NULL;
}
}

static VSTPluginWrapper *FindWrapperByWindow(HWND hwnd) {
return window_to_wrapper;
}

void redrawWindow(void) {
// Save host GL context
HDC hostHDC = ::wglGetCurrentDC();
HGLRC hostHGLRC = ::wglGetCurrentContext();
printf("xxx vstgltest: WM_PAINT: hostHDC=%p hostGLRC=%p\n", hostHDC, hostHGLRC);

// Bind plugin GL context
printf("xxx vstgltest: WM_PAINT: pluginHDC=%p pluginGLRC=%p\n", editor.hdc, hglrc);
::wglMakeCurrent(editor.hdc, hglrc);

// Draw something
::glClearColor(0.0, 1.0, clear_color, 1.0);
clear_color += 0.05f;
if(clear_color >= 1.0f)
clear_color -= 1.0f;
::glClear(GL_COLOR_BUFFER_BIT);
::glFlush();
::wglSwapLayerBuffers(editor.hdc, WGL_SWAP_MAIN_PLANE);
// Restore host GL context
::wglMakeCurrent(hostHDC, hostHGLRC);
}

private:
// the host callback (a function pointer)
VSTHostCallback _vstHostCallback;

// the actual structure required by the host
VSTPlugin _vstPlugin;
};

const char *VSTPluginWrapper::registered_class_name = NULL;
VSTPluginWrapper *VSTPluginWrapper::window_to_wrapper = NULL;

extern "C" LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {

switch(message)
{
case WM_CREATE:
printf("xxx vstgltest: WM_CREATE\n");
break;

case WM_DESTROY:
printf("xxx vstgltest: WM_DESTROY\n");
break;

case WM_LBUTTONDOWN:
printf("xxx vstgltest: WM_LBUTTONDOWN\n");
break;

case WM_LBUTTONUP:
printf("xxx vstgltest: WM_LBUTTONUP\n");
break;

case WM_PAINT:
// https://docs.microsoft.com/en-us/windows/desktop/api/Winuser/nf-winuser-redrawwindow
printf("xxx vstgltest: WM_PAINT\n");
VSTPluginWrapper *wrapper = VSTPluginWrapper::FindWrapperByWindow(hWnd);
wrapper->redrawWindow();
break;
}

return DefWindowProc(hWnd, message, wParam, lParam);
}

/*******************************************
* Callbacks: Host -> Plugin
*
* Defined here because they are used in the rest of the code later
*/

/**
* This is the callback that will be called to process the samples in the case of single precision. This is where the
* meat of the logic happens!
*
* @param vstPlugin the object returned by VSTPluginMain
* @param inputs an array of array of input samples. You read from it. First dimension is for inputs, second dimension is for samples: inputs[numInputs][sampleFrames]
* @param outputs an array of array of output samples. You write to it. First dimension is for outputs, second dimension is for samples: outputs[numOuputs][sampleFrames]
* @param sampleFrames the number of samples (second dimension in both arrays)
*/
void VSTPluginProcessSamplesFloat32(VSTPlugin *vstPlugin, float **inputs, float **outputs, VstInt32 sampleFrames)
{
// we can get a hold to our C++ class since we stored it in the `object` field (see constructor)
VSTPluginWrapper *wrapper = static_cast<VSTPluginWrapper *>(vstPlugin->object);

// code speaks for itself: for each input (2 when stereo input), iterating over every sample and writing the
// result in the outputs array after multiplying by 0.5 (which result in a 3dB attenuation of the sound)
for(int i = 0; i < wrapper->getNumInputs(); i++)
{
auto inputSamples = inputs[i];
auto outputSamples = outputs[i];
for(int j = 0; j < sampleFrames; j++)
{
outputSamples[j] = inputSamples[j] * 0.5f;
}
}
}

/**
* This is the callback that will be called to process the samples in the case of double precision. This is where the
* meat of the logic happens!
*
* @param vstPlugin the object returned by VSTPluginMain
* @param inputs an array of array of input samples. You read from it. First dimension is for inputs, second dimension is for samples: inputs[numInputs][sampleFrames]
* @param outputs an array of array of output samples. You write to it. First dimension is for outputs, second dimension is for samples: outputs[numOuputs][sampleFrames]
* @param sampleFrames the number of samples (second dimension in both arrays)
*/
void VSTPluginProcessSamplesFloat64(VSTPlugin *vstPlugin, double **inputs, double **outputs, VstInt32 sampleFrames)
{
// we can get a hold to our C++ class since we stored it in the `object` field (see constructor)
VSTPluginWrapper *wrapper = static_cast<VSTPluginWrapper *>(vstPlugin->object);

// code speaks for itself: for each input (2 when stereo input), iterating over every sample and writing the
// result in the outputs array after multiplying by 0.5 (which result in a 3dB attenuation of the sound)
for(int i = 0; i < wrapper->getNumInputs(); i++)
{
auto inputSamples = inputs[i];
auto outputSamples = outputs[i];
for(int j = 0; j < sampleFrames; j++)
{
outputSamples[j] = inputSamples[j] * 0.5;
}
}
}

/**
* This is the plugin called by the host to communicate with the plugin, mainly to request information (like the
* vendor string, the plugin category...) or communicate state/changes (like open/close, frame rate...)
*
* @param vstPlugin the object returned by VSTPluginMain
* @param opCode defined in aeffect.h/AEffectOpcodes and which continues in aeffectx.h/AEffectXOpcodes for a grand
* total of 79 of them! Only a few of them are implemented in this small plugin.
* @param index depend on the opcode
* @param value depend on the opcode
* @param ptr depend on the opcode
* @param opt depend on the opcode
* @return depend on the opcode (0 is ok when you don't implement an opcode...)
*/
VstIntPtr VSTPluginDispatcher(VSTPlugin *vstPlugin, VstInt32 opCode, VstInt32 index, VstIntPtr value, void *ptr, float opt)
{
printf("vstgltest: called VSTPluginDispatcher(%d)\n", opCode);

VstIntPtr r = 0;

// we can get a hold to our C++ class since we stored it in the `object` field (see constructor)
VSTPluginWrapper *wrapper = static_cast<VSTPluginWrapper *>(vstPlugin->object);
// see aeffect.h/AEffectOpcodes and aeffectx.h/AEffectXOpcodes for details on all of them
switch(opCode)
{
// request for the category of the plugin: in this case it is an effect since it is modifying the input (as opposed
// to generating sound)
case effGetPlugCategory:
return kPlugCategEffect;

// called by the host when the plugin was called... time to reclaim memory!
case effClose:
delete wrapper;
break;

case effGetEffectName:
::strncpy((char*)ptr, "VST GL Test", kVstMaxEffectNameLen);
r = 1;
break;

// request for the vendor string (usually used in the UI for plugin grouping)
case effGetVendorString:
strncpy(static_cast<char *>(ptr), "bsp", kVstMaxVendorStrLen);
r = 1;
break;

// request for the version
case effGetVendorVersion:
return PLUGIN_VERSION;

case effEditIdle:
if(NULL != wrapper->editor.hwnd)
{
printf("xxx vstgltest: redraw window\n");
// (void)::RedrawWindow(wrapper->hwnd, NULL, NULL, RDW_INTERNALPAINT);
//(void)::UpdateWindow(wrapper->hwnd);
if(::IsWindowVisible(wrapper->editor.hwnd))
{
wrapper->redrawWindow();
}
}
break;

case effEditGetRect:
// Query editor window geometry
// ptr: ERect* (on Windows)
if(NULL != ptr) // yeah, this should never be NULL
{
// ...
wrapper->editor_rect.left = EDITWIN_X;
wrapper->editor_rect.top = EDITWIN_Y;
wrapper->editor_rect.right = EDITWIN_X + EDITWIN_W;
wrapper->editor_rect.bottom = EDITWIN_Y + EDITWIN_H;
*(void**)ptr = (void*) &wrapper->editor_rect;
r = 1;
}
else
{
r = 0;
}
break;

#if 0
case effEditTop:
// deprecated in vst2.4
r = 0;
break;
#endif

case effEditOpen:
// Show editor window
// ptr: native window handle (hWnd on Windows)
wrapper->openEditor((HWND)ptr);
r = 1;
break;

case effEditClose:
// Hide editor window
wrapper->closeEditor();
r = 1;
break;

// ignoring all other opcodes
default:
printf("Unknown opCode %d [ignored] \n", opCode);
break;
}

return r;
}

/**
* Used for parameter setting (not used by this plugin)
*/
void VSTPluginSetParameter(VSTPlugin *vstPlugin, VstInt32 index, float parameter)
{
printf("called VSTPluginSetParameter(%d, %f)\n", index, parameter);
// we can get a hold to our C++ class since we stored it in the `object` field (see constructor)
VSTPluginWrapper *wrapper = static_cast<VSTPluginWrapper *>(vstPlugin->object);
}

/**
* Used for parameter (not used by this plugin)
*/
float VSTPluginGetParameter(VSTPlugin *vstPlugin, VstInt32 index)
{
printf("called VSTPluginGetParameter(%d)\n", index);
// we can get a hold to our C++ class since we stored it in the `object` field (see constructor)
VSTPluginWrapper *wrapper = static_cast<VSTPluginWrapper *>(vstPlugin->object);
return 0;
}

/**
* Main constructor for our C++ class
*/
VSTPluginWrapper::VSTPluginWrapper(audioMasterCallback vstHostCallback,
VstInt32 vendorUniqueID,
VstInt32 vendorVersion,
VstInt32 numParams,
VstInt32 numPrograms,
VstInt32 numInputs,
VstInt32 numOutputs) :
_vstHostCallback(vstHostCallback)
{
// Make sure that the memory is properly initialized
memset(&_vstPlugin, 0, sizeof(_vstPlugin));

// this field must be set with this constant...
_vstPlugin.magic = kEffectMagic;

// storing this object into the VSTPlugin so that it can be retrieved when called back (see callbacks for use)
_vstPlugin.object = this;

// specifying that we handle both single and double precision (there are other flags see aeffect.h/VstAEffectFlags)
_vstPlugin.flags = effFlagsCanReplacing | effFlagsCanDoubleReplacing | effFlagsHasEditor;

// initializing the plugin with the various values
_vstPlugin.uniqueID = vendorUniqueID;
_vstPlugin.version = vendorVersion;
_vstPlugin.numParams = numParams;
_vstPlugin.numPrograms = numPrograms;
_vstPlugin.numInputs = numInputs;
_vstPlugin.numOutputs = numOutputs;

// setting the callbacks to the previously defined functions
_vstPlugin.dispatcher = VSTPluginDispatcher;
_vstPlugin.getParameter = VSTPluginGetParameter;
_vstPlugin.setParameter = VSTPluginSetParameter;
_vstPlugin.processReplacing = VSTPluginProcessSamplesFloat32;
_vstPlugin.processDoubleReplacing = VSTPluginProcessSamplesFloat64;

parent_hwnd = NULL;

hidden.hwnd = NULL;
hidden.hdc = NULL;

editor.hwnd = NULL;
editor.hdc = NULL;

hglrc = NULL;

createHiddenWindow();
}

/**
* Destructor called when the plugin is closed (see VSTPluginDispatcher with effClose opCode). In this very simply plugin
* there is nothing to do but in general the memory that gets allocated MUST be freed here otherwise there might be a
* memory leak which may end up slowing down and/or crashing the host
*/
VSTPluginWrapper::~VSTPluginWrapper() {
destroyHiddenWindow();
}

/**
* Implementation of the main entry point of the plugin
*/
VST_EXPORT VSTPlugin *VSTPluginMain(VSTHostCallback vstHostCallback)
{
printf("called VSTPluginMain... \n");

// simply create our plugin C++ class
VSTPluginWrapper *plugin =
new VSTPluginWrapper(vstHostCallback,
CCONST('u', 's', 'a', '§'), // registered with Steinberg (http://service.steinberg.de/databases/plugin.nsf/plugIn?openForm)
PLUGIN_VERSION, // version
0, // no params
0, // no programs
2, // 2 inputs
2); // 2 outputs

// return the plugin per the contract of the API
return plugin->getVSTPlugin();
}

+ 527
- 0
other/vst2_lglw_debug_plugin/plugin.cpp__SIMPLE View File

@@ -0,0 +1,527 @@


#include <aeffect.h>
#include <aeffectx.h>
#include <stdio.h>

#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#include <wingdi.h>
#define VST_EXPORT extern "C" __declspec(dllexport)
#else
#define VST_EXPORT extern
#endif

#include <GL/GL.h>

#define EDITWIN_X 20
#define EDITWIN_Y 20
#define EDITWIN_W 640
#define EDITWIN_H 480
#define EDITWIN_CLASS_NAME "VeeSeeVSTWindow"

/*
* I find the naming a bit confusing so I decided to use more meaningful names instead.
*/

/**
* The VSTHostCallback is a function pointer so that the plugin can communicate with the host (not used in this small example)
*/
typedef audioMasterCallback VSTHostCallback;

/**
* The VSTPlugin structure (AEffect) contains information about the plugin (like version, number of inputs, ...) and
* callbacks so that the host can call the plugin to do its work. The primary callback will be `processReplacing` for
* single precision (float) sample processing (or `processDoubleReplacing` for double precision (double)).
*/
typedef AEffect VSTPlugin;


// Since the host is expecting a very specific API we need to make sure it has C linkage (not C++)
extern "C" {

/*
* This is the main entry point to the VST plugin.
*
* The host (DAW like Maschine, Ableton Live, Reason, ...) will look for this function with this exact API.
*
* It is the equivalent to `int main(int argc, char *argv[])` for a C executable.
*
* @param vstHostCallback is a callback so that the plugin can communicate with the host (not used in this small example)
* @return a pointer to the AEffect structure
*/
VST_EXPORT VSTPlugin *VSTPluginMain(VSTHostCallback vstHostCallback);

// note this looks like this without the type aliases (and is obviously 100% equivalent)
// extern AEffect *VSTPluginMain(audioMasterCallback audioMaster);

}

/*
* Constant for the version of the plugin. For example 1100 for version 1.1.0.0
*/
const VstInt32 PLUGIN_VERSION = 1000;

extern "C" LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

/**
* Encapsulates the plugin as a C++ class. It will keep both the host callback and the structure required by the
* host (VSTPlugin). This class will be stored in the `VSTPlugin.object` field (circular reference) so that it can
* be accessed when the host calls the plugin back (for example in `processDoubleReplacing`).
*/
class VSTPluginWrapper
{
public:
ERect editor_rect;
HWND parent_hwnd; // created by host
HWND hwnd;
HDC hdc;
HGLRC hglrc;

float clear_color = 0.0f;

static const char *registered_class_name;
static VSTPluginWrapper *window_to_wrapper;

public:
VSTPluginWrapper(VSTHostCallback vstHostCallback,
VstInt32 vendorUniqueID,
VstInt32 vendorVersion,
VstInt32 numParams,
VstInt32 numPrograms,
VstInt32 numInputs,
VstInt32 numOutputs);

~VSTPluginWrapper();

inline VSTPlugin *getVSTPlugin()
{
return &_vstPlugin;
}

inline VstInt32 getNumInputs() const
{
return _vstPlugin.numInputs;
}

inline VstInt32 getNumOutputs() const
{
return _vstPlugin.numOutputs;
}

void openEditor(HWND _hwnd) {
parent_hwnd = _hwnd;

if(NULL == registered_class_name)
{
WNDCLASS wc;
::ZeroMemory(&wc, sizeof(wc));
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.hInstance = ::GetModuleHandle(NULL);
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = EDITWIN_CLASS_NAME;

if(!::RegisterClass(&wc))
{
// something went terribly wrong
printf("[---] vstgltest: failed to register window class\n");
return;
}

registered_class_name = EDITWIN_CLASS_NAME;
}

DWORD dwExStyle = 0;
DWORD dwStyle = WS_CHILD | WS_VISIBLE;

hwnd = ::CreateWindowEx(dwExStyle,
EDITWIN_CLASS_NAME,
"Test",
dwStyle,
0/*xpos*/, 0/*ypos*/,
EDITWIN_W, EDITWIN_H,
parent_hwnd,
NULL, // window menu
::GetModuleHandle(NULL),
NULL
);

window_to_wrapper = this;

PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //Flags
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
32, // Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, // Number of bits for the depthbuffer
8, // Number of bits for the stencilbuffer
0, // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};

hdc = ::GetDC(hwnd);

int pfmt = ::ChoosePixelFormat(hdc, &pfd);
printf("xxx vstgltest: pfmt=%d", pfmt);
::SetPixelFormat(hdc, pfmt, &pfd);

hglrc = ::wglCreateContext(hdc);
}

void closeEditor(void) {
if(NULL != hwnd)
{
::wglDeleteContext(hglrc);
::DestroyWindow(hwnd);

// (todo) unregister when last window is closed
::UnregisterClass(EDITWIN_CLASS_NAME, ::GetModuleHandle(NULL));
registered_class_name = NULL;

window_to_wrapper = NULL;
}
}

static VSTPluginWrapper *FindWrapperByWindow(HWND hwnd) {
return window_to_wrapper;
}

void redrawWindow(void) {
// Save host GL context
HDC hostHDC = ::wglGetCurrentDC();
HGLRC hostHGLRC = ::wglGetCurrentContext();
printf("xxx vstgltest: WM_PAINT: hostHDC=%p hostGLRC=%p\n", hostHDC, hostHGLRC);

// Bind plugin GL context
printf("xxx vstgltest: WM_PAINT: pluginHDC=%p pluginGLRC=%p\n", hdc, hglrc);
::wglMakeCurrent(hdc, hglrc);

// Draw something
::glClearColor(0.0, 1.0, clear_color, 1.0);
clear_color += 0.05f;
if(clear_color >= 1.0f)
clear_color -= 1.0f;
::glClear(GL_COLOR_BUFFER_BIT);
::glFlush();
::wglSwapLayerBuffers(hdc, WGL_SWAP_MAIN_PLANE);
// Restore host GL context
::wglMakeCurrent(hostHDC, hostHGLRC);
}

private:
// the host callback (a function pointer)
VSTHostCallback _vstHostCallback;

// the actual structure required by the host
VSTPlugin _vstPlugin;
};

const char *VSTPluginWrapper::registered_class_name = NULL;
VSTPluginWrapper *VSTPluginWrapper::window_to_wrapper = NULL;

extern "C" LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {

switch(message)
{
case WM_CREATE:
printf("xxx vstgltest: WM_CREATE\n");
break;

case WM_DESTROY:
printf("xxx vstgltest: WM_DESTROY\n");
break;

case WM_LBUTTONDOWN:
printf("xxx vstgltest: WM_LBUTTONDOWN\n");
break;

case WM_LBUTTONUP:
printf("xxx vstgltest: WM_LBUTTONUP\n");
break;

case WM_PAINT:
// https://docs.microsoft.com/en-us/windows/desktop/api/Winuser/nf-winuser-redrawwindow
printf("xxx vstgltest: WM_PAINT\n");
VSTPluginWrapper *wrapper = VSTPluginWrapper::FindWrapperByWindow(hWnd);
wrapper->redrawWindow();
break;
}

return DefWindowProc(hWnd, message, wParam, lParam);
}

/*******************************************
* Callbacks: Host -> Plugin
*
* Defined here because they are used in the rest of the code later
*/

/**
* This is the callback that will be called to process the samples in the case of single precision. This is where the
* meat of the logic happens!
*
* @param vstPlugin the object returned by VSTPluginMain
* @param inputs an array of array of input samples. You read from it. First dimension is for inputs, second dimension is for samples: inputs[numInputs][sampleFrames]
* @param outputs an array of array of output samples. You write to it. First dimension is for outputs, second dimension is for samples: outputs[numOuputs][sampleFrames]
* @param sampleFrames the number of samples (second dimension in both arrays)
*/
void VSTPluginProcessSamplesFloat32(VSTPlugin *vstPlugin, float **inputs, float **outputs, VstInt32 sampleFrames)
{
// we can get a hold to our C++ class since we stored it in the `object` field (see constructor)
VSTPluginWrapper *wrapper = static_cast<VSTPluginWrapper *>(vstPlugin->object);

// code speaks for itself: for each input (2 when stereo input), iterating over every sample and writing the
// result in the outputs array after multiplying by 0.5 (which result in a 3dB attenuation of the sound)
for(int i = 0; i < wrapper->getNumInputs(); i++)
{
auto inputSamples = inputs[i];
auto outputSamples = outputs[i];
for(int j = 0; j < sampleFrames; j++)
{
outputSamples[j] = inputSamples[j] * 0.5f;
}
}
}

/**
* This is the callback that will be called to process the samples in the case of double precision. This is where the
* meat of the logic happens!
*
* @param vstPlugin the object returned by VSTPluginMain
* @param inputs an array of array of input samples. You read from it. First dimension is for inputs, second dimension is for samples: inputs[numInputs][sampleFrames]
* @param outputs an array of array of output samples. You write to it. First dimension is for outputs, second dimension is for samples: outputs[numOuputs][sampleFrames]
* @param sampleFrames the number of samples (second dimension in both arrays)
*/
void VSTPluginProcessSamplesFloat64(VSTPlugin *vstPlugin, double **inputs, double **outputs, VstInt32 sampleFrames)
{
// we can get a hold to our C++ class since we stored it in the `object` field (see constructor)
VSTPluginWrapper *wrapper = static_cast<VSTPluginWrapper *>(vstPlugin->object);

// code speaks for itself: for each input (2 when stereo input), iterating over every sample and writing the
// result in the outputs array after multiplying by 0.5 (which result in a 3dB attenuation of the sound)
for(int i = 0; i < wrapper->getNumInputs(); i++)
{
auto inputSamples = inputs[i];
auto outputSamples = outputs[i];
for(int j = 0; j < sampleFrames; j++)
{
outputSamples[j] = inputSamples[j] * 0.5;
}
}
}

/**
* This is the plugin called by the host to communicate with the plugin, mainly to request information (like the
* vendor string, the plugin category...) or communicate state/changes (like open/close, frame rate...)
*
* @param vstPlugin the object returned by VSTPluginMain
* @param opCode defined in aeffect.h/AEffectOpcodes and which continues in aeffectx.h/AEffectXOpcodes for a grand
* total of 79 of them! Only a few of them are implemented in this small plugin.
* @param index depend on the opcode
* @param value depend on the opcode
* @param ptr depend on the opcode
* @param opt depend on the opcode
* @return depend on the opcode (0 is ok when you don't implement an opcode...)
*/
VstIntPtr VSTPluginDispatcher(VSTPlugin *vstPlugin, VstInt32 opCode, VstInt32 index, VstIntPtr value, void *ptr, float opt)
{
printf("vstgltest: called VSTPluginDispatcher(%d)\n", opCode);

VstIntPtr r = 0;

// we can get a hold to our C++ class since we stored it in the `object` field (see constructor)
VSTPluginWrapper *wrapper = static_cast<VSTPluginWrapper *>(vstPlugin->object);
// see aeffect.h/AEffectOpcodes and aeffectx.h/AEffectXOpcodes for details on all of them
switch(opCode)
{
// request for the category of the plugin: in this case it is an effect since it is modifying the input (as opposed
// to generating sound)
case effGetPlugCategory:
return kPlugCategEffect;

// called by the host when the plugin was called... time to reclaim memory!
case effClose:
delete wrapper;
break;

case effGetEffectName:
::strncpy((char*)ptr, "VST GL Test", kVstMaxEffectNameLen);
r = 1;
break;

// request for the vendor string (usually used in the UI for plugin grouping)
case effGetVendorString:
strncpy(static_cast<char *>(ptr), "bsp", kVstMaxVendorStrLen);
r = 1;
break;

// request for the version
case effGetVendorVersion:
return PLUGIN_VERSION;

case effEditIdle:
if(NULL != wrapper->hwnd)
{
printf("xxx vstgltest: redraw window\n");
// (void)::RedrawWindow(wrapper->hwnd, NULL, NULL, RDW_INTERNALPAINT);
//(void)::UpdateWindow(wrapper->hwnd);
if(::IsWindowVisible(wrapper->hwnd))
{
wrapper->redrawWindow();
}
}
break;

case effEditGetRect:
// Query editor window geometry
// ptr: ERect* (on Windows)
if(NULL != ptr) // yeah, this should never be NULL
{
// ...
wrapper->editor_rect.left = EDITWIN_X;
wrapper->editor_rect.top = EDITWIN_Y;
wrapper->editor_rect.right = EDITWIN_X + EDITWIN_W;
wrapper->editor_rect.bottom = EDITWIN_Y + EDITWIN_H;
*(void**)ptr = (void*) &wrapper->editor_rect;
r = 1;
}
else
{
r = 0;
}
break;

#if 0
case effEditTop:
// deprecated in vst2.4
r = 0;
break;
#endif

case effEditOpen:
// Show editor window
// ptr: native window handle (hWnd on Windows)
wrapper->openEditor((HWND)ptr);
r = 1;
break;

case effEditClose:
// Hide editor window
wrapper->closeEditor();
r = 1;
break;

// ignoring all other opcodes
default:
printf("Unknown opCode %d [ignored] \n", opCode);
break;
}

return r;
}

/**
* Used for parameter setting (not used by this plugin)
*/
void VSTPluginSetParameter(VSTPlugin *vstPlugin, VstInt32 index, float parameter)
{
printf("called VSTPluginSetParameter(%d, %f)\n", index, parameter);
// we can get a hold to our C++ class since we stored it in the `object` field (see constructor)
VSTPluginWrapper *wrapper = static_cast<VSTPluginWrapper *>(vstPlugin->object);
}

/**
* Used for parameter (not used by this plugin)
*/
float VSTPluginGetParameter(VSTPlugin *vstPlugin, VstInt32 index)
{
printf("called VSTPluginGetParameter(%d)\n", index);
// we can get a hold to our C++ class since we stored it in the `object` field (see constructor)
VSTPluginWrapper *wrapper = static_cast<VSTPluginWrapper *>(vstPlugin->object);
return 0;
}

/**
* Main constructor for our C++ class
*/
VSTPluginWrapper::VSTPluginWrapper(audioMasterCallback vstHostCallback,
VstInt32 vendorUniqueID,
VstInt32 vendorVersion,
VstInt32 numParams,
VstInt32 numPrograms,
VstInt32 numInputs,
VstInt32 numOutputs) :
_vstHostCallback(vstHostCallback)
{
// Make sure that the memory is properly initialized
memset(&_vstPlugin, 0, sizeof(_vstPlugin));

// this field must be set with this constant...
_vstPlugin.magic = kEffectMagic;

// storing this object into the VSTPlugin so that it can be retrieved when called back (see callbacks for use)
_vstPlugin.object = this;

// specifying that we handle both single and double precision (there are other flags see aeffect.h/VstAEffectFlags)
_vstPlugin.flags = effFlagsCanReplacing | effFlagsCanDoubleReplacing | effFlagsHasEditor;

// initializing the plugin with the various values
_vstPlugin.uniqueID = vendorUniqueID;
_vstPlugin.version = vendorVersion;
_vstPlugin.numParams = numParams;
_vstPlugin.numPrograms = numPrograms;
_vstPlugin.numInputs = numInputs;
_vstPlugin.numOutputs = numOutputs;

// setting the callbacks to the previously defined functions
_vstPlugin.dispatcher = VSTPluginDispatcher;
_vstPlugin.getParameter = VSTPluginGetParameter;
_vstPlugin.setParameter = VSTPluginSetParameter;
_vstPlugin.processReplacing = VSTPluginProcessSamplesFloat32;
_vstPlugin.processDoubleReplacing = VSTPluginProcessSamplesFloat64;

parent_hwnd = NULL;
hwnd = NULL;
hdc = NULL;
hglrc = NULL;
}

/**
* Destructor called when the plugin is closed (see VSTPluginDispatcher with effClose opCode). In this very simply plugin
* there is nothing to do but in general the memory that gets allocated MUST be freed here otherwise there might be a
* memory leak which may end up slowing down and/or crashing the host
*/
VSTPluginWrapper::~VSTPluginWrapper()
{
}

/**
* Implementation of the main entry point of the plugin
*/
VST_EXPORT VSTPlugin *VSTPluginMain(VSTHostCallback vstHostCallback)
{
printf("called VSTPluginMain... \n");

// simply create our plugin C++ class
VSTPluginWrapper *plugin =
new VSTPluginWrapper(vstHostCallback,
CCONST('u', 's', 'a', '§'), // registered with Steinberg (http://service.steinberg.de/databases/plugin.nsf/plugIn?openForm)
PLUGIN_VERSION, // version
0, // no params
0, // no programs
2, // 2 inputs
2); // 2 outputs

// return the plugin per the contract of the API
return plugin->getVSTPlugin();
}

+ 31
- 0
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db.sln View File

@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2024
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "m3db", "m3db\m3db.vcxproj", "{ADEB3292-4BBF-4B20-9A11-3D8076423F16}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{ADEB3292-4BBF-4B20-9A11-3D8076423F16}.Debug|x64.ActiveCfg = Debug|x64
{ADEB3292-4BBF-4B20-9A11-3D8076423F16}.Debug|x64.Build.0 = Debug|x64
{ADEB3292-4BBF-4B20-9A11-3D8076423F16}.Debug|x86.ActiveCfg = Debug|Win32
{ADEB3292-4BBF-4B20-9A11-3D8076423F16}.Debug|x86.Build.0 = Debug|Win32
{ADEB3292-4BBF-4B20-9A11-3D8076423F16}.Release|x64.ActiveCfg = Release|x64
{ADEB3292-4BBF-4B20-9A11-3D8076423F16}.Release|x64.Build.0 = Release|x64
{ADEB3292-4BBF-4B20-9A11-3D8076423F16}.Release|x86.ActiveCfg = Release|Win32
{ADEB3292-4BBF-4B20-9A11-3D8076423F16}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A1B75069-8782-4AB1-A661-12FED71250D4}
EndGlobalSection
EndGlobal

BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/dllmain.cpp View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/m3db.cpp View File


+ 167
- 0
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/m3db.vcxproj View File

@@ -0,0 +1,167 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{ADEB3292-4BBF-4B20-9A11-3D8076423F16}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>m3db</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;M3DB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>f:\dev\vstsdk2.4</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;M3DB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;M3DB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>f:\dev\vstsdk2.4</AdditionalIncludeDirectories>
<DebugInformationFormat>None</DebugInformationFormat>
<PrecompiledHeaderFile />
<PrecompiledHeaderOutputFile />
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;M3DB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);_CRT_SECURE_NO_DEPRECATE</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>F:\git\VeeSeeVSTRack\dep\lglw;f:\dev\vstsdk2.4\pluginterfaces\vst2.x\</AdditionalIncludeDirectories>
<DebugInformationFormat>None</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\..\..\..\..\git\VeeSeeVSTRack\dep\lglw\lglw_windows.c" />
<ClCompile Include="..\..\..\..\..\..\..\git\VeeSeeVSTRack\dep\lglw\lglw_windows_cpp.cpp" />
<ClCompile Include="..\..\..\plugin.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\..\..\..\..\git\VeeSeeVSTRack\dep\lglw\lglw.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

+ 33
- 0
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/m3db.vcxproj.filters View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\plugin.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\..\..\..\git\VeeSeeVSTRack\dep\lglw\lglw_windows.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\..\..\..\git\VeeSeeVSTRack\dep\lglw\lglw_windows_cpp.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\..\..\..\..\git\VeeSeeVSTRack\dep\lglw\lglw.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

+ 4
- 0
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/m3db.vcxproj.user View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/stdafx.cpp View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/stdafx.h View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/targetver.h View File


+ 5
- 0
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/m3db.Build.CppClean.log View File

@@ -0,0 +1,5 @@
f:\projects\research\pongasoft_vst24-hello-world-master\m3db\vs2017\m3db\m3db\x64\debug\vc141.pdb
f:\projects\research\pongasoft_vst24-hello-world-master\m3db\vs2017\m3db\m3db\x64\debug\vc141.idb
f:\projects\research\pongasoft_vst24-hello-world-master\m3db\vs2017\m3db\m3db\x64\debug\m3db.tlog\cl.command.1.tlog
f:\projects\research\pongasoft_vst24-hello-world-master\m3db\vs2017\m3db\m3db\x64\debug\m3db.tlog\cl.read.1.tlog
f:\projects\research\pongasoft_vst24-hello-world-master\m3db\vs2017\m3db\m3db\x64\debug\m3db.tlog\cl.write.1.tlog

+ 2
- 0
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/m3db.log View File

@@ -0,0 +1,2 @@
 plugin.cpp
f:\projects\research\pongasoft_vst24-hello-world-master\m3db\plugin.cpp(3): fatal error C1083: Cannot open include file: 'aeffect.h': No such file or directory

BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/m3db.tlog/CL.command.1.tlog View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/m3db.tlog/CL.read.1.tlog View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/m3db.tlog/CL.write.1.tlog View File


+ 2
- 0
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/m3db.tlog/m3db.lastbuildstate View File

@@ -0,0 +1,2 @@
#TargetFrameworkVersion=v4.0:PlatformToolSet=v141:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=10.0.16299.0
Debug|x64|F:\Projects\research\pongasoft_vst24-hello-world-master\M3dB\vs2017\m3db\|

+ 0
- 0
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/m3db.tlog/unsuccessfulbuild View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/vc141.idb View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Debug/vc141.pdb View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/lglw_windows.obj View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/lglw_windows_cpp.obj View File


+ 15
- 0
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.Build.CppClean.log View File

@@ -0,0 +1,15 @@
f:\projects\research\vst24_gl_test\m3db\vs2017\m3db\m3db\x64\release\plugin.obj
f:\projects\research\vst24_gl_test\m3db\vs2017\m3db\m3db\x64\release\lglw_windows.obj
f:\projects\research\vst24_gl_test\m3db\vs2017\m3db\m3db\x64\release\lglw_windows_cpp.obj
f:\projects\research\vst24_gl_test\m3db\vs2017\m3db\x64\release\m3db.dll
f:\projects\research\vst24_gl_test\m3db\vs2017\m3db\x64\release\m3db.lib
f:\projects\research\vst24_gl_test\m3db\vs2017\m3db\x64\release\m3db.exp
f:\projects\research\vst24_gl_test\m3db\vs2017\m3db\x64\release\m3db.ipdb
f:\projects\research\vst24_gl_test\m3db\vs2017\m3db\x64\release\m3db.iobj
f:\projects\research\vst24_gl_test\m3db\vs2017\m3db\m3db\x64\release\m3db.tlog\cl.command.1.tlog
f:\projects\research\vst24_gl_test\m3db\vs2017\m3db\m3db\x64\release\m3db.tlog\cl.read.1.tlog
f:\projects\research\vst24_gl_test\m3db\vs2017\m3db\m3db\x64\release\m3db.tlog\cl.write.1.tlog
f:\projects\research\vst24_gl_test\m3db\vs2017\m3db\m3db\x64\release\m3db.tlog\link.command.1.tlog
f:\projects\research\vst24_gl_test\m3db\vs2017\m3db\m3db\x64\release\m3db.tlog\link.read.1.tlog
f:\projects\research\vst24_gl_test\m3db\vs2017\m3db\m3db\x64\release\m3db.tlog\link.write.1.tlog
f:\projects\research\vst24_gl_test\m3db\vs2017\m3db\m3db\x64\release\m3db.tlog\m3db.write.1u.tlog

+ 8
- 0
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.log View File

@@ -0,0 +1,8 @@
 lglw_windows.c
lglw_windows_cpp.cpp
plugin.cpp
Creating library F:\Projects\research\vst24_gl_test\M3dB\vs2017\m3db\x64\Release\m3db.lib and object F:\Projects\research\vst24_gl_test\M3dB\vs2017\m3db\x64\Release\m3db.exp
Generating code
All 57 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
Finished generating code
m3db.vcxproj -> F:\Projects\research\vst24_gl_test\M3dB\vs2017\m3db\x64\Release\m3db.dll

BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/CL.command.1.tlog View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/CL.read.1.tlog View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/CL.write.1.tlog View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/link.command.1.tlog View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/link.read.1.tlog View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/link.write.1.tlog View File


+ 2
- 0
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/m3db.lastbuildstate View File

@@ -0,0 +1,2 @@
#TargetFrameworkVersion=v4.0:PlatformToolSet=v141:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=10.0.16299.0
Release|x64|F:\Projects\research\vst24_gl_test\M3dB\vs2017\m3db\|

BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/m3db.tlog/m3db.write.1u.tlog View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/m3db/x64/Release/plugin.obj View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/x64/Release/m3db.iobj View File


BIN
other/vst2_lglw_debug_plugin/vs2017/m3db/x64/Release/m3db.ipdb View File


+ 5
- 1
src/util/logger.cpp View File

@@ -56,7 +56,11 @@ static void loggerLogVa(LoggerLevel level, const char *file, int line, const cha
if (global->logger.logFile == LOG_STDFILE)
fprintf(global->logger.logFile, "\x1B[0m");
vfprintf(global->logger.logFile, format, args);
vprintf(format, args); // xxx

// TODO
// At least for me, this will cause a complete crash from __strlen_avx512
// vprintf(format, args); // xxx

printf("\n"); // xxx
fprintf(global->logger.logFile, "\n");
fflush(global->logger.logFile);


Loading…
Cancel
Save