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.

298 lines
8.5KB

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