You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

284 lines
8.1KB

  1. // vst_eureka_standalone_test.cpp : Defines the entry point for the console application.
  2. //
  3. #define DLL_PATH "../../vst2_bin/veeseevstrack_effect.dll"
  4. // #define SO_PATH "../../vst2_bin/veeseevstrack_effect.so"
  5. // #define SO_PATH "../vst2_lglw_debug_plugin/debug_lglw.so"
  6. // #define SO_PATH "/usr/local/lib/vst/debug_lglw.so"
  7. #define SO_PATH "../../vst2_bin/debug_lglw.so"
  8. #include <yac.h>
  9. #ifdef YAC_WIN32
  10. #include "stdafx.h"
  11. #include <windows.h>
  12. #else
  13. #include <dlfcn.h>
  14. #include <unistd.h>
  15. #include <X11/Xlib.h>
  16. #include <X11/Xutil.h>
  17. #include <X11/Xos.h>
  18. #include <X11/Xatom.h>
  19. #endif
  20. #include <aeffect.h>
  21. #include <aeffectx.h>
  22. typedef AEffect* (*PluginEntryProc) (audioMasterCallback audioMaster);
  23. #ifndef YAC_WIN32
  24. // https://github.com/Ardour/ardour/blob/master/gtk2_ardour/linux_vst_gui_support.cc
  25. void *getXWindowProperty(Display* display, Window window, Atom atom)
  26. {
  27. int userSize;
  28. unsigned long bytes;
  29. unsigned long userCount;
  30. unsigned char *data;
  31. Atom userType;
  32. // LXVST_xerror = false;
  33. /*Use our own Xerror handler while we're in here - in an
  34. attempt to stop the brain dead default Xerror behaviour of
  35. qutting the entire application because of e.g. an invalid
  36. window ID*/
  37. // XErrorHandler olderrorhandler = XSetErrorHandler(TempErrorHandler);
  38. printf("xxx getXWindowProperty: window=%lu\n", window);
  39. XGetWindowProperty(display,
  40. window,
  41. atom,
  42. 0/*offset*/,
  43. 2/*length*/,
  44. false/*delete*/,
  45. AnyPropertyType,
  46. &userType/*actual_type_return*/,
  47. &userSize/*actual_format_return*/,
  48. &userCount/*nitems_return*/,
  49. &bytes/*bytes_after_return / partial reads*/,
  50. &data);
  51. union {
  52. long l[2];
  53. void *any;
  54. } uptr;
  55. uptr.any = 0;
  56. printf("xxx getXWindowProperty: userSize=%d userCount=%lu bytes=%lu data=%p\n", userSize, userCount, bytes, data);
  57. if(NULL != data)
  58. {
  59. if(userCount == 1)
  60. {
  61. // 32-bit
  62. uptr.l[0] = *(long*)data;
  63. uptr.l[1] = 0;
  64. }
  65. else if(2 == userCount)
  66. {
  67. // 64-bit
  68. uptr.l[0] = ((long*)data)[0];
  69. uptr.l[1] = ((long*)data)[1];
  70. }
  71. XFree(data);
  72. }
  73. // XSetErrorHandler(olderrorhandler);
  74. /*Hopefully this will return zero if the property is not set*/
  75. printf("xxx getXWindowProperty: return callback addr=%p\n", uptr.any);
  76. return uptr.any;
  77. }
  78. #endif
  79. static VstIntPtr VSTCALLBACK HostCallback(AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt) {
  80. static VstInt32 lastOpcode = -1;
  81. static VstIntPtr lastTimeMask = ~0;
  82. VstIntPtr result = 0;
  83. lastOpcode = opcode;
  84. (void)lastOpcode;
  85. (void)lastTimeMask;
  86. return result;
  87. }
  88. float *inputBuffers[48];
  89. float *outputBuffers[48];
  90. void open_and_close(void) {
  91. #ifdef YAC_WIN32
  92. HINSTANCE dllHandle = ::LoadLibraryA(DLL_PATH);
  93. #else
  94. void *dllHandle = ::dlopen(SO_PATH, RTLD_NOW);
  95. if(NULL == dllHandle)
  96. {
  97. printf("Failed to load library %s: %s", SO_PATH, dlerror());
  98. return;
  99. }
  100. #endif
  101. #ifndef YAC_WIN32
  102. Display *d;
  103. Window w;
  104. int s;
  105. d = XOpenDisplay(NULL);
  106. s = DefaultScreen(d);
  107. #endif
  108. for(int i = 0; i < 48; i++)
  109. {
  110. inputBuffers[i] = new float[4096];
  111. outputBuffers[i] = new float[4096];
  112. }
  113. if(NULL != dllHandle)
  114. {
  115. #ifdef YAC_WIN32
  116. PluginEntryProc mainProc = (PluginEntryProc) ::GetProcAddress((HMODULE)dllHandle, "VSTPluginMain");
  117. if(NULL == mainProc)
  118. {
  119. mainProc = (PluginEntryProc) ::GetProcAddress((HMODULE)dllHandle, "main");
  120. }
  121. #else
  122. PluginEntryProc mainProc = (PluginEntryProc) ::dlsym(dllHandle, "VSTPluginMain");
  123. if(NULL == mainProc)
  124. {
  125. mainProc = (PluginEntryProc) ::dlsym(dllHandle, "main");
  126. }
  127. #endif
  128. if(NULL != mainProc)
  129. {
  130. AEffect *effect;
  131. printf("xxx calling mainProc\n");
  132. effect = mainProc(HostCallback);
  133. printf("xxx mainProc returned effect=%p\n", effect);
  134. if(NULL != effect)
  135. {
  136. ERect *rect = 0;
  137. effect->dispatcher(effect, effEditGetRect, 0, 0, (void*)&rect, 0.0f);
  138. printf("xxx effEditGetRect returned left=%d top=%d right=%d bottom=%d\n", rect->left, rect->top, rect->right, rect->bottom);
  139. #ifndef YAC_WIN32
  140. w = XCreateSimpleWindow(d, RootWindow(d, s), rect->left, rect->top, (rect->right - rect->left), (rect->bottom - rect->top), 1,
  141. BlackPixel(d, s), WhitePixel(d, s)
  142. );
  143. XSelectInput(d, w, ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask | FocusChangeMask);
  144. XMapRaised(d, w);
  145. XFlush(d);
  146. #endif
  147. printf("xxx calling effect->dispatcher<effOpen>\n");
  148. effect->dispatcher(effect, effOpen, 0, 0, NULL, 0.0f);
  149. printf("xxx effect->dispatcher<effOpen> returned\n");
  150. #ifdef YAC_WIN32
  151. VstIntPtr ip = effect->dispatcher(effect, effEditOpen, 0, 0, NULL/*hWnd*/, 0.0f);
  152. #else
  153. VstIntPtr ip = effect->dispatcher(effect, effEditOpen, 0, 0, (void*)(w)/*hWnd*/, 0.0f);
  154. #endif
  155. (void)ip;
  156. sleep(2);
  157. #ifndef YAC_WIN32
  158. void *result = getXWindowProperty(d, w, XInternAtom(d, "_XEventProc", false));
  159. if(result == 0)
  160. {
  161. printf("xxx no XEventProc found\n");
  162. }
  163. else
  164. {
  165. void (* eventProc) (void * event);
  166. int evIdx = 0;
  167. eventProc = (void (*) (void* event))result;
  168. printf("xxx XEventProc found\n");
  169. for(;;)
  170. {
  171. XEvent xev;
  172. XNextEvent(d, &xev);
  173. printf("xxx call XEventProc[%d]\n", evIdx++);
  174. eventProc(&xev);
  175. }
  176. }
  177. #endif
  178. printf("xxx calling effect->dispatcher<effEditIdle>\n");
  179. effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
  180. sleep(1);
  181. printf("xxx calling effect->dispatcher<effEditIdle>\n");
  182. effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
  183. sleep(1);
  184. printf("xxx calling effect->dispatcher<effEditClose>\n");
  185. effect->dispatcher(effect, effEditClose, 0, 0, NULL, 0.0f);
  186. sleep(1);
  187. printf("xxx calling effect->dispatcher<effEditOpen> again\n");
  188. #ifdef YAC_WIN32
  189. effect->dispatcher(effect, effEditOpen, 0, 0, NULL/*hWnd*/, 0.0f);
  190. #else
  191. effect->dispatcher(effect, effEditOpen, 0, 0, (void*)(w)/*hWnd*/, 0.0f);
  192. #endif
  193. sleep(1);
  194. printf("xxx calling effect->dispatcher<effEditIdle>\n");
  195. effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
  196. sleep(1);
  197. printf("xxx call processreplacing\n");
  198. for(int i = 0; i < 1024; i++)
  199. {
  200. effect->processReplacing(effect, inputBuffers, outputBuffers, (VstInt32)64);
  201. }
  202. printf("xxx calling effect->dispatcher<effEditClose>\n");
  203. effect->dispatcher(effect, effEditClose, 0, 0, NULL, 0.0f);
  204. sleep(1);
  205. printf("xxx calling effect->dispatcher<effClose>\n");
  206. effect->dispatcher(effect, effClose, 0, 0, NULL, 0.0f);
  207. sleep(1);
  208. #ifndef YAC_WIN32
  209. XDestroyWindow(d, w);
  210. #endif
  211. }
  212. }
  213. else
  214. {
  215. printf("[---] failed to find mainProc\n");
  216. }
  217. printf("xxx debug_host: closing library\n");
  218. #ifdef YAC_WIN32
  219. ::FreeLibrary(dllHandle);
  220. #else
  221. ::dlclose(dllHandle);
  222. #endif
  223. printf("xxx debug_host: library closed\n");
  224. }
  225. for(int i = 0; i < 48; i++)
  226. {
  227. delete [] inputBuffers[i];
  228. delete [] outputBuffers[i];
  229. }
  230. #ifndef YAC_WIN32
  231. XCloseDisplay(d);
  232. #endif
  233. }
  234. int main() {
  235. for(int i = 0; i < 5; i++)
  236. {
  237. open_and_close();
  238. }
  239. printf("xxx debug_host: exiting\n");
  240. return 0;
  241. }