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.

364 lines
11KB

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