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.

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