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.

342 lines
10KB

  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. static void *loc_getProperty(Display *_display, Window _window, const char *_name) {
  32. int userSize;
  33. unsigned long bytes;
  34. unsigned long userCount;
  35. unsigned char *data;
  36. Atom userType;
  37. Atom atom = XInternAtom(_display, _name, False);
  38. // (note) 64bit properties need to be read with two XGetWindowProperty() calls.
  39. // When using just one call and setting the 'length' to 2, the upper 32bit (second array element) will be 0xFFFFffff.
  40. XGetWindowProperty(_display,
  41. _window,
  42. atom,
  43. 0/*offset*/,
  44. 1/*length*/,
  45. False/*delete*/,
  46. AnyPropertyType,
  47. &userType/*actual_type_return*/,
  48. &userSize/*actual_format_return*/,
  49. &userCount/*nitems_return*/,
  50. &bytes/*bytes_after_return / partial reads*/,
  51. &data);
  52. union {
  53. uint32_t ui[2];
  54. void *any;
  55. } uptr;
  56. uptr.any = 0;
  57. printf("xxx debug_host: loc_getProperty: LOWER userSize=%d userCount=%lu bytes=%lu data=%p\n", userSize, userCount, bytes, data);
  58. if(NULL != data)
  59. {
  60. if(userCount >= 1)
  61. {
  62. if(userCount >= 2)
  63. {
  64. printf("xxx debug_host: loc_getProperty: lo=0x%08x hi=0x%08x\n", ((uint32_t*)data)[0], ((uint32_t*)data)[1]);
  65. }
  66. // lower 32-bit
  67. uptr.ui[0] = *(long*)data;
  68. uptr.ui[1] = 0;
  69. printf("xxx lower=0x%08x\n", uptr.ui[0]);
  70. // // printf("xxx upper=0x%08x\n", uptr.ui[1]);
  71. XFree(data);
  72. // // if(userCount >= 2)
  73. {
  74. XGetWindowProperty(_display,
  75. _window,
  76. atom,
  77. 1/*offset*/,
  78. 1/*length*/,
  79. False/*delete*/,
  80. AnyPropertyType,
  81. &userType/*actual_type_return*/,
  82. &userSize/*actual_format_return*/,
  83. &userCount/*nitems_return*/,
  84. &bytes/*bytes_after_return / partial reads*/,
  85. &data);
  86. printf("xxx lglw_linux: loc_getProperty: UPPER userSize=%d userCount=%lu bytes=%lu data=%p\n", userSize, userCount, bytes, data);
  87. if(NULL != data)
  88. {
  89. // upper 32-bit
  90. uptr.ui[1] = *(long*)data;
  91. printf("xxx upper=0x%08x\n", uptr.ui[1]);
  92. XFree(data);
  93. }
  94. }
  95. }
  96. }
  97. printf("xxx debug_host: loc_getProperty: return value=%p\n", uptr.any);
  98. return uptr.any;
  99. }
  100. #endif // !YAC_WIN32
  101. static VstIntPtr VSTCALLBACK HostCallback(AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt) {
  102. static VstInt32 lastOpcode = -1;
  103. static VstIntPtr lastTimeMask = ~0;
  104. VstIntPtr result = 0;
  105. lastOpcode = opcode;
  106. (void)lastOpcode;
  107. (void)lastTimeMask;
  108. switch(opcode)
  109. {
  110. default:
  111. printf("xxx debug_host: HostCallback: unhandled opcode=%d index=%d value=%ld ptr=%p opt=%f\n", opcode, index, value, ptr, opt);
  112. break;
  113. case audioMasterVersion:
  114. result = 2400;
  115. break;
  116. }
  117. return result;
  118. }
  119. float *inputBuffers[48];
  120. float *outputBuffers[48];
  121. void open_and_close(void) {
  122. #ifdef YAC_WIN32
  123. HINSTANCE dllHandle = ::LoadLibraryA(DLL_PATH);
  124. #else
  125. void *dllHandle = ::dlopen(SO_PATH, RTLD_NOW);
  126. if(NULL == dllHandle)
  127. {
  128. printf("Failed to load library %s: %s", SO_PATH, dlerror());
  129. return;
  130. }
  131. #endif
  132. #ifndef YAC_WIN32
  133. Display *d;
  134. Window w;
  135. int s;
  136. d = XOpenDisplay(NULL);
  137. s = DefaultScreen(d);
  138. #endif
  139. for(int i = 0; i < 48; i++)
  140. {
  141. inputBuffers[i] = new float[4096];
  142. outputBuffers[i] = new float[4096];
  143. }
  144. if(NULL != dllHandle)
  145. {
  146. #ifdef YAC_WIN32
  147. PluginEntryProc mainProc = (PluginEntryProc) ::GetProcAddress((HMODULE)dllHandle, "VSTPluginMain");
  148. if(NULL == mainProc)
  149. {
  150. mainProc = (PluginEntryProc) ::GetProcAddress((HMODULE)dllHandle, "main");
  151. }
  152. #else
  153. PluginEntryProc mainProc = (PluginEntryProc) ::dlsym(dllHandle, "VSTPluginMain");
  154. if(NULL == mainProc)
  155. {
  156. mainProc = (PluginEntryProc) ::dlsym(dllHandle, "main");
  157. }
  158. #endif
  159. if(NULL != mainProc)
  160. {
  161. AEffect *effect;
  162. printf("xxx calling mainProc\n");
  163. effect = mainProc(HostCallback);
  164. printf("xxx mainProc returned effect=%p\n", effect);
  165. if(NULL != effect)
  166. {
  167. ERect *rectp = 0;
  168. ERect rect;
  169. effect->dispatcher(effect, effEditGetRect, 0, 0, (void*)&rectp, 0.0f);
  170. if(NULL != rectp)
  171. {
  172. rect = *rectp;
  173. }
  174. else
  175. {
  176. rect.top = 0;
  177. rect.left = 0;
  178. rect.right = 640;
  179. rect.bottom = 480;
  180. }
  181. printf("xxx effEditGetRect returned left=%d top=%d right=%d bottom=%d\n", rect.left, rect.top, rect.right, rect.bottom);
  182. #ifndef YAC_WIN32
  183. w = XCreateSimpleWindow(d, RootWindow(d, s), rect.left, rect.top, (rect.right - rect.left), (rect.bottom - rect.top), 1,
  184. BlackPixel(d, s), WhitePixel(d, s)
  185. );
  186. XSelectInput(d, w, ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask | FocusChangeMask);
  187. XMapRaised(d, w);
  188. XFlush(d);
  189. #endif
  190. #if 0
  191. // Event test (=> keyboard events are working)
  192. {
  193. int evIdx = 0;
  194. for(;;)
  195. {
  196. XEvent xev;
  197. XNextEvent(d, &xev);
  198. printf("xxx XNextEvent[%d]\n", evIdx++);
  199. }
  200. }
  201. #endif
  202. printf("xxx calling effect->dispatcher<effOpen>\n");
  203. effect->dispatcher(effect, effOpen, 0, 0, NULL, 0.0f);
  204. printf("xxx effect->dispatcher<effOpen> returned\n");
  205. #ifdef YAC_WIN32
  206. VstIntPtr ip = effect->dispatcher(effect, effEditOpen, 0, 0, NULL/*hWnd*/, 0.0f);
  207. #else
  208. VstIntPtr ip = effect->dispatcher(effect, effEditOpen, 0, 0, (void*)(w)/*hWnd*/, 0.0f);
  209. #endif
  210. (void)ip;
  211. sleep(2);
  212. #ifndef YAC_WIN32
  213. void *result = loc_getProperty(d, w, "_XEventProc");
  214. if(result == 0)
  215. {
  216. printf("xxx no XEventProc found\n");
  217. }
  218. else
  219. {
  220. void (* eventProc) (void * event);
  221. int evIdx = 0;
  222. eventProc = (void (*) (void* event))result;
  223. printf("xxx XEventProc found\n");
  224. for(;;)
  225. {
  226. XEvent xev;
  227. XNextEvent(d, &xev);
  228. printf("xxx call XEventProc[%d]\n", evIdx++);
  229. eventProc(&xev);
  230. }
  231. }
  232. #endif
  233. printf("xxx calling effect->dispatcher<effEditIdle>\n");
  234. effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
  235. sleep(1);
  236. printf("xxx calling effect->dispatcher<effEditIdle>\n");
  237. effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
  238. sleep(1);
  239. printf("xxx calling effect->dispatcher<effEditClose>\n");
  240. effect->dispatcher(effect, effEditClose, 0, 0, NULL, 0.0f);
  241. sleep(1);
  242. printf("xxx calling effect->dispatcher<effEditOpen> again\n");
  243. #ifdef YAC_WIN32
  244. effect->dispatcher(effect, effEditOpen, 0, 0, NULL/*hWnd*/, 0.0f);
  245. #else
  246. effect->dispatcher(effect, effEditOpen, 0, 0, (void*)(w)/*hWnd*/, 0.0f);
  247. #endif
  248. sleep(1);
  249. printf("xxx calling effect->dispatcher<effEditIdle>\n");
  250. effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
  251. sleep(1);
  252. printf("xxx call processreplacing\n");
  253. for(int i = 0; i < 1024; i++)
  254. {
  255. effect->processReplacing(effect, inputBuffers, outputBuffers, (VstInt32)64);
  256. }
  257. printf("xxx calling effect->dispatcher<effEditClose>\n");
  258. effect->dispatcher(effect, effEditClose, 0, 0, NULL, 0.0f);
  259. sleep(1);
  260. printf("xxx calling effect->dispatcher<effClose>\n");
  261. effect->dispatcher(effect, effClose, 0, 0, NULL, 0.0f);
  262. sleep(1);
  263. #ifndef YAC_WIN32
  264. XDestroyWindow(d, w);
  265. #endif
  266. }
  267. }
  268. else
  269. {
  270. printf("[---] failed to find mainProc\n");
  271. }
  272. printf("xxx debug_host: closing library\n");
  273. #ifdef YAC_WIN32
  274. ::FreeLibrary(dllHandle);
  275. #else
  276. ::dlclose(dllHandle);
  277. #endif
  278. printf("xxx debug_host: library closed\n");
  279. }
  280. for(int i = 0; i < 48; i++)
  281. {
  282. delete [] inputBuffers[i];
  283. delete [] outputBuffers[i];
  284. }
  285. #ifndef YAC_WIN32
  286. XCloseDisplay(d);
  287. #endif
  288. }
  289. int main() {
  290. for(int i = 0; i < 5; i++)
  291. {
  292. open_and_close();
  293. }
  294. printf("xxx debug_host: exiting\n");
  295. return 0;
  296. }