From 63189be1df97d5a8659af8b76d1ca6b10d0e9627 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 27 Feb 2009 17:11:21 +0000 Subject: vestige-based VST support, back-ported from 2.0-ongoing git-svn-id: svn://localhost/ardour2/branches/3.0@4703 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/fst/vstwin.c | 753 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 483 insertions(+), 270 deletions(-) (limited to 'libs/fst/vstwin.c') diff --git a/libs/fst/vstwin.c b/libs/fst/vstwin.c index 55061c2b72..fc9ac0c999 100644 --- a/libs/fst/vstwin.c +++ b/libs/fst/vstwin.c @@ -5,14 +5,12 @@ #include #include #include - -//#include -//#include -//#include -//#include +#include #include "fst.h" +#include +#include struct ERect{ short top; @@ -21,138 +19,28 @@ struct ERect{ short right; }; -static pthread_mutex_t plugin_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t plugin_mutex; static FST* fst_first = NULL; +const char magic[] = "FST Plugin State v002"; DWORD gui_thread_id = 0; -static char* message_name (int message) -{ - switch (message) { - case 0x0000: - return "WM_NULL"; - - case 0x0001: - return "WM_CREATE"; - - case 0x0002: - return "WM_DESTROY"; - - case 0x0003: - return "WM_MOVE"; - - case 0x0004: - return "WM_SIZEWAIT"; - - case 0x0005: - return "WM_SIZE"; - - case 0x0006: - return "WM_ACTIVATE"; - - case 0x0007: - return "WM_SETFOCUS"; - - case 0x0008: - return "WM_KILLFOCUS"; - - case 0x0009: - return "WM_SETVISIBLE"; - - case 0x000a: - return "WM_ENABLE"; - - case 0x000b: - return "WM_SETREDRAW"; - - case 0x000c: - return "WM_SETTEXT"; - - case 0x000d: - return "WM_GETTEXT"; - - case 0x000e: - return "WM_GETTEXTLENGTH"; - - case 0x000f: - return "WM_PAINT"; - - case 0x0010: - return "WM_CLOSE"; - - case 0x0011: - return "WM_QUERYENDSESSION"; - - case 0x0012: - return "WM_QUIT"; +extern boolean g_quit; - case 0x0013: - return "WM_QUERYOPEN"; - case 0x0014: - return "WM_ERASEBKGND"; - case 0x0015: - return "WM_SYSCOLORCHANGE"; - case 0x0016: - return "WM_ENDSESSION"; +#define DELAYED_WINDOW 1 - case 0x0017: - return "WM_SYSTEMERROR"; - case 0x0018: - return "WM_SHOWWINDOW"; - - case 0x0019: - return "WM_CTLCOLOR"; - - case 0x001a: - return "WM_WININICHANGE"; - - case 0x001b: - return "WM_DEVMODECHANGE"; - - case 0x001c: - return "WM_ACTIVATEAPP"; - - case 0x001d: - return "WM_FONTCHANGE"; - - case 0x001e: - return "WM_TIMECHANGE"; - - case 0x001f: - return "WM_CANCELMODE"; - - case 0x0020: - return "WM_SETCURSOR"; - - case 0x0021: - return "WM_MOUSEACTIVATE"; - - case 0x0022: - return "WM_CHILDACTIVATE"; - - case 0x0023: - return "WM_QUEUESYNC"; - - case 0x0024: - return "WM_GETMINMAXINFO"; - - default: - break; - } - return "--- OTHER ---"; -} - static LRESULT WINAPI my_window_proc (HWND w, UINT msg, WPARAM wp, LPARAM lp) { - FST* fst; + FST* fst=NULL; + LRESULT result; // if (msg != WM_TIMER) { -// fst_error ("window callback handler, msg = 0x%x (%s) win=%p\n", msg, message_name (msg), w); +// fst_error ("window callback handler, msg = 0x%x win=%p\n", msg, w); // } switch (msg) { @@ -161,39 +49,57 @@ my_window_proc (HWND w, UINT msg, WPARAM wp, LPARAM lp) break; case WM_CLOSE: + //printf("wtf.\n" ); PostQuitMessage (0); - case WM_DESTROY: case WM_NCDESTROY: /* we should never get these */ //return 0; break; - +#if 0 case WM_PAINT: - if ((fst = GetPropA (w, "fst_ptr")) != NULL) { - if (fst->window && !fst->been_activated) { - fst->been_activated = TRUE; - pthread_cond_signal (&fst->window_status_change); - pthread_mutex_unlock (&fst->lock); + if ((fst = GetPropA (w, "fst_ptr")) != NULL) { + if (fst->window && !fst->been_activated) { + fst->been_activated = TRUE; + pthread_cond_signal (&fst->window_status_change); + pthread_mutex_unlock (&fst->lock); + } } - } break; +#endif + +#if 0 + case WM_TIMER: + fst = GetPropA( w, "fst_ptr" ); + if( !fst ) { + printf( "Timer without fst_ptr Prop :(\n" ); + return 0; + } + + fst->plugin->dispatcher(fst->plugin, effEditIdle, 0, 0, NULL, 0.0f); + if( fst->wantIdle ) + fst->plugin->dispatcher(fst->plugin, 53, 0, 0, NULL, 0.0f); + return 0; +#endif + + default: break; } return DefWindowProcA (w, msg, wp, lp ); + //return 0; } static FST* fst_new () { FST* fst = (FST*) calloc (1, sizeof (FST)); - pthread_mutex_init (&fst->lock, NULL); pthread_cond_init (&fst->window_status_change, NULL); - + pthread_cond_init (&fst->plugin_dispatcher_called, NULL); + fst->want_program = -1; return fst; } @@ -204,102 +110,11 @@ fst_handle_new () return fst; } -int -fst_create_editor (FST* fst) -{ - HMODULE hInst; - HWND window; - - /* "guard point" to trap errors that occur during plugin loading */ - - /* Note: fst->lock is held while this function is called */ - - if (!(fst->plugin->flags & effFlagsHasEditor)) { - fst_error ("Plugin \"%s\" has no editor", fst->handle->name); - return -1; - } - - if ((hInst = GetModuleHandleA (NULL)) == NULL) { - fst_error ("can't get module handle"); - return 1; - } - -// if ((window = CreateWindowExA (WS_EX_TOOLWINDOW | WS_EX_TRAYWINDOW, "FST", fst->handle->name, - if ((window = CreateWindowExA (0, "FST", fst->handle->name, - (WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX), - 0, 0, 1, 1, - NULL, NULL, - hInst, - NULL)) == NULL) { - fst_error ("cannot create editor window"); - return 1; - } - - if (!SetPropA (window, "fst_ptr", fst)) { - fst_error ("cannot set fst_ptr on window"); - } - - fst->window = window; - fst->xid = (int) GetPropA (window, "__wine_x11_whole_window"); - - { - struct ERect* er; - - ShowWindow (fst->window, SW_SHOW); - - fst->plugin->dispatcher (fst->plugin, effEditOpen, 0, 0, fst->window, 0 ); - fst->plugin->dispatcher (fst->plugin, effEditGetRect, 0, 0, &er, 0 ); - - fst->width = er->right-er->left; - fst->height = er->bottom-er->top; - - SetWindowPos (fst->window, 0, 0, 0, er->right-er->left+8, er->bottom-er->top+26, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOZORDER); - } - - return 0; -} - -void -fst_destroy_editor (FST* fst) -{ - pthread_mutex_lock (&fst->lock); - if (fst->window) { - fst->destroy = TRUE; - if (!PostThreadMessageA (gui_thread_id, WM_USER, 0, 0)) { - fst_error ("could not post message to gui thread"); - } - pthread_cond_wait (&fst->window_status_change, &fst->lock); - - } - pthread_mutex_unlock (&fst->lock); -} - -void -fst_event_loop_remove_plugin (FST* fst) -{ - FST* p; - FST* prev; - - for (p = fst_first, prev = NULL; p->next; prev = p, p = p->next) { - if (p == fst) { - if (prev) { - prev->next = p->next; - } - } - } - - if (fst_first == fst) { - fst_first = fst_first->next; - } - -} - -void debreak( void ) { printf( "debreak\n" ); } - DWORD WINAPI gui_event_loop (LPVOID param) { MSG msg; FST* fst; + char c; HMODULE hInst; HWND window; @@ -314,29 +129,19 @@ DWORD WINAPI gui_event_loop (LPVOID param) if ((window = CreateWindowExA (0, "FST", "dummy", WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX, - CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, CW_USEDEFAULT, + 9999, 9999, + 1, 1, NULL, NULL, hInst, NULL )) == NULL) { fst_error ("cannot create dummy timer window"); } - if (!SetTimer (window, 1000, 100, NULL)) { + if (!SetTimer (window, 1000, 20, NULL)) { fst_error ("cannot set timer on dummy window"); } - while (1) { - - GetMessageA (&msg, NULL, 0,0); - - if (msg.message == WM_SYSTEMERROR) { - /* sent when this thread is supposed to exist */ - break; - } - - if (msg.message == WM_KEYDOWN) debreak(); - + while (GetMessageA (&msg, NULL, 0,0)) { TranslateMessage( &msg ); DispatchMessageA (&msg); @@ -344,7 +149,7 @@ DWORD WINAPI gui_event_loop (LPVOID param) and run idle callbacks */ - if( msg.message == WM_TIMER ) { + if( msg.message == WM_TIMER ) { pthread_mutex_lock (&plugin_mutex); again: for (fst = fst_first; fst; fst = fst->next) { @@ -366,6 +171,7 @@ again: if (fst->window == NULL) { pthread_mutex_lock (&fst->lock); + fst_error ("Creating window for FST plugin %s", fst->handle->name); if (fst_create_editor (fst)) { fst_error ("cannot create editor for plugin %s", fst->handle->name); fst_event_loop_remove_plugin (fst); @@ -373,28 +179,66 @@ again: pthread_mutex_unlock (&fst->lock); goto again; } - /* condition/unlock handled when we receive WM_ACTIVATE */ + /* condition/unlock: it was signalled & unlocked in fst_create_editor() */ + } + if(fst->want_program != -1 ) { + fst->plugin->dispatcher (fst->plugin, effSetProgram, 0, fst->want_program, NULL, 0); + fst->want_program = -1; + } + + if(fst->dispatcher_wantcall) { + + pthread_mutex_lock (&fst->lock); + fst->dispatcher_retval = fst->plugin->dispatcher( fst->plugin, fst->dispatcher_opcode, + fst->dispatcher_index, + fst->dispatcher_val, + fst->dispatcher_ptr, + fst->dispatcher_opt ); + fst->dispatcher_wantcall = 0; + pthread_cond_signal (&fst->plugin_dispatcher_called); + pthread_mutex_unlock (&fst->lock); } + pthread_mutex_lock (&fst->lock); fst->plugin->dispatcher (fst->plugin, effEditIdle, 0, 0, NULL, 0); + if( fst->wantIdle ) { + fst->plugin->dispatcher (fst->plugin, 53, 0, 0, NULL, 0); + } + pthread_mutex_unlock (&fst->lock); } pthread_mutex_unlock (&plugin_mutex); } } - fst_error ("FST GUI event loop has quit!"); + fprintf (stderr, "VST GUI EVENT LOOP THREAD EXIT\n"); return 0; } int -fst_init () +fst_init (void* possible_hmodule) { - WNDCLASSA wc; + WNDCLASSEX wclass; HMODULE hInst; - - if ((hInst = GetModuleHandleA (NULL)) == NULL) { - fst_error ("can't get module handle"); - return -1; + + if (possible_hmodule) { + hInst = (HMODULE) possible_hmodule; + } else if ((hInst = GetModuleHandleA (NULL)) == NULL) { + fst_error ("can't get module handle"); + return -1; } + wclass.cbSize = sizeof(WNDCLASSEX); + wclass.style = 0; + wclass.lpfnWndProc = my_window_proc; + wclass.cbClsExtra = 0; + wclass.cbWndExtra = 0; + wclass.hInstance = hInst; + wclass.hIcon = LoadIcon(hInst, "FST"); + wclass.hCursor = LoadCursor(0, IDI_APPLICATION); +// wclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wclass.lpszMenuName = "MENU_FST"; + wclass.lpszClassName = "FST"; + wclass.hIconSm = 0; + +#if 0 wc.style = 0; wc.lpfnWndProc = my_window_proc; wc.cbClsExtra = 0; @@ -403,32 +247,28 @@ fst_init () wc.hIcon = LoadIconA( hInst, "FST"); wc.hCursor = LoadCursorA( NULL, IDI_APPLICATION ); wc.hbrBackground = GetStockObject( BLACK_BRUSH ); - wc.lpszMenuName = "MENU_FST"; + wc.lpszMenuName = "FSTMENU"; wc.lpszClassName = "FST"; + //wc.hIconSm = 0; +#endif - if (!RegisterClassA(&wc)){ - return 1; + if (!RegisterClassExA(&wclass)){ + printf( "Class register failed :(\n" ); + return -1; } + fst_error ("Startup win32 GUI thread\n"); + if (CreateThread (NULL, 0, gui_event_loop, NULL, 0, NULL) == NULL) { fst_error ("could not create new thread proxy"); return -1; } - return 0; } -void -fst_finish () -{ - PostThreadMessageA (gui_thread_id, WM_SYSTEMERROR, 0, 0); -} - int fst_run_editor (FST* fst) { - /* Add the FST to the list of all that should be handled by the GUI thread */ - pthread_mutex_lock (&plugin_mutex); if (fst_first == NULL) { @@ -441,11 +281,6 @@ fst_run_editor (FST* fst) p->next = fst; } - if (!PostThreadMessageA (gui_thread_id, WM_USER, 0, 0)) { - fst_error ("could not post message to gui thread"); - return -1; - } - pthread_mutex_unlock (&plugin_mutex); /* wait for the plugin editor window to be created (or not) */ @@ -457,17 +292,196 @@ fst_run_editor (FST* fst) pthread_mutex_unlock (&fst->lock); if (!fst->window) { - fst_error ("no window created for VST plugin editor"); return -1; } return 0; } +int +fst_call_dispatcher (FST *fst, int opcode, int index, int val, void *ptr, float opt) +{ + pthread_mutex_lock (&fst->lock); + fst->dispatcher_opcode = opcode; + fst->dispatcher_index = index; + fst->dispatcher_val = val; + fst->dispatcher_ptr = ptr; + fst->dispatcher_opt = opt; + fst->dispatcher_wantcall = 1; + + pthread_cond_wait (&fst->plugin_dispatcher_called, &fst->lock); + pthread_mutex_unlock (&fst->lock); + + return fst->dispatcher_retval; +} + +int +fst_create_editor (FST* fst) +{ + HMODULE hInst; + char class[20]; + HWND window; + struct ERect* er; + + /* "guard point" to trap errors that occur during plugin loading */ + + /* Note: fst->lock is held while this function is called */ + + if (!(fst->plugin->flags & effFlagsHasEditor)) { + fst_error ("Plugin \"%s\" has no editor", fst->handle->name); + return -1; + } + + if ((hInst = GetModuleHandleA (NULL)) == NULL) { + fst_error ("can't get module handle"); + return 1; + } + +// if ((window = CreateWindowExA (WS_EX_TOOLWINDOW | WS_EX_TRAYWINDOW, "FST", fst->handle->name, + if ((window = CreateWindowExA (0, "FST", fst->handle->name, + (WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX), +// (WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX), + 9999,9999,1,1, +// CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, + hInst, + NULL)) == NULL) { + fst_error ("cannot create editor window"); + return 1; + } + + if (!SetPropA (window, "fst_ptr", fst)) { + fst_error ("cannot set fst_ptr on window"); + } + + fst->window = window; +// fst->xid = (int) GetPropA (window, "__wine_x11_whole_window"); + + + //printf( "effEditOpen......\n" ); + fst->plugin->dispatcher (fst->plugin, effEditOpen, 0, 0, fst->window, 0 ); + fst->plugin->dispatcher (fst->plugin, effEditGetRect, 0, 0, &er, 0 ); + + fst->width = er->right-er->left; + fst->height = er->bottom-er->top; + //printf( "get rect ses... %d,%d\n", fst->width, fst->height ); + + //SetWindowPos (fst->window, 0, 9999, 9999, er->right-er->left+8, er->bottom-er->top+26, 0); + SetWindowPos (fst->window, 0, 9999, 9999, 2, 2, 0); + ShowWindow (fst->window, SW_SHOWNA); + //SetWindowPos (fst->window, 0, 0, 0, er->right-er->left+8, er->bottom-er->top+26, SWP_NOMOVE|SWP_NOZORDER); + + fst->xid = (int) GetPropA (window, "__wine_x11_whole_window"); + printf( "And xid = %x\n", fst->xid ); + fst->been_activated = TRUE; + printf ("Signalling window ready\n"); + pthread_cond_signal (&fst->window_status_change); + pthread_mutex_unlock (&fst->lock); + + return 0; +} + +void +fst_move_window_into_view (FST* fst) +{ + if (fst->window) { + SetWindowPos (fst->window, 0, 0, 0, fst->width, fst->height+24, 0); + ShowWindow (fst->window, SW_SHOWNA); + } +} + +void +fst_destroy_editor (FST* fst) +{ + FST* p; + FST* prev; + + pthread_mutex_lock (&fst->lock); + if (fst->window) { + fst->destroy = TRUE; + //if (!PostThreadMessageA (gui_thread_id, WM_USER, 0, 0)) { + //if (!PostThreadMessageA (gui_thread_id, WM_QUIT, 0, 0)) { + // fst_error ("could not post message to gui thread"); + //} + pthread_cond_wait (&fst->window_status_change, &fst->lock); + + } + pthread_mutex_unlock (&fst->lock); +} + +void +fst_event_loop_remove_plugin (FST* fst) +{ + FST* p; + FST* prev; + + for (p = fst_first, prev = NULL; p->next; prev = p, p = p->next) { + if (p == fst) { + if (prev) { + prev->next = p->next; + } + } + } + + if (fst_first == fst) { + fst_first = fst_first->next; + } + +} + +HMODULE +fst_load_vst_library(const char * path) +{ + HMODULE dll; + char * full_path; + char * envdup; + char * vst_path; + size_t len1; + size_t len2; + + if ((dll = LoadLibraryA (path)) != NULL) { + return dll; + } + + envdup = getenv ("VST_PATH"); + if (envdup == NULL) { + return NULL; + } + + envdup = strdup (envdup); + if (envdup == NULL) { + fst_error ("strdup failed"); + return NULL; + } + + len2 = strlen(path); + + vst_path = strtok (envdup, ":"); + while (vst_path != NULL) { + fst_error ("\"%s\"", vst_path); + len1 = strlen(vst_path); + full_path = malloc (len1 + 1 + len2 + 1); + memcpy(full_path, vst_path, len1); + full_path[len1] = '/'; + memcpy(full_path + len1 + 1, path, len2); + full_path[len1 + 1 + len2] = '\0'; + + if ((dll = LoadLibraryA (full_path)) != NULL) { + break; + } + + vst_path = strtok (NULL, ":"); + } + + free(envdup); + + return dll; +} + FSTHandle* fst_load (const char *path) { - char* buf; + char* buf, *buf2; FSTHandle* fhandle; char* period; @@ -509,14 +523,12 @@ fst_load (const char *path) *period = '\0'; } - if ((fhandle->dll = LoadLibraryA (buf)) == NULL) { + if ((fhandle->dll = fst_load_vst_library (buf)) == NULL) { fst_unload (fhandle); return NULL; } - typedef AEffect* (*entryFunctionType)(audioMasterCallback); - - if ((fhandle->main_entry = (entryFunctionType) GetProcAddress (fhandle->dll, "main")) == NULL) { + if ((fhandle->main_entry = (main_entry_t) GetProcAddress (fhandle->dll, "main")) == NULL) { fst_unload (fhandle); return NULL; } @@ -574,6 +586,7 @@ fst_instantiate (FSTHandle* fhandle, audioMasterCallback amc, void* userptr) //fst->plugin->dispatcher (fst->plugin, effMainsChanged, 0, 0, NULL, 0); fst->handle->plugincnt++; + fst->wantIdle = 0; return fst; } @@ -596,3 +609,203 @@ fst_get_XID (FST* fst) { return fst->xid; } + +float htonf (float v) +{ + float result; + char * fin = (char*)&v; + char * fout = (char*)&result; + fout[0] = fin[3]; + fout[1] = fin[2]; + fout[2] = fin[1]; + fout[3] = fin[0]; + return result; +} + +#if 0 +int fst_load_state (FST * fst, char * filename) +{ + FILE * f = fopen (filename, "rb"); + if (f) { + char testMagic[sizeof (magic)]; + fread (&testMagic, sizeof (magic), 1, f); + if (strcmp (testMagic, magic)) { + printf ("File corrupt\n"); + return FALSE; + } + + char productString[64]; + char vendorString[64]; + char effectName[64]; + char testString[64]; + unsigned length; + int success; + + fread (&length, sizeof (unsigned), 1, f); + length = htonl (length); + fread (productString, length, 1, f); + productString[length] = 0; + printf ("Product string: %s\n", productString); + + success = fst_call_dispatcher( fst, effGetProductString, 0, 0, testString, 0 ); + if (success == 1) { + if (strcmp (testString, productString) != 0) { + printf ("Product string mismatch! Plugin has: %s\n", testString); + fclose (f); + return FALSE; + } + } else if (length != 0) { + printf ("Product string mismatch! Plugin has none.\n", testString); + fclose (f); + return FALSE; + } + + fread (&length, sizeof (unsigned), 1, f); + length = htonl (length); + fread (effectName, length, 1, f); + effectName[length] = 0; + printf ("Effect name: %s\n", effectName); + + success = fst_call_dispatcher( fst, effGetEffectName, 0, 0, testString, 0 ); + if (success == 1) { + if (strcmp (testString, effectName) != 0) { + printf ("Effect name mismatch! Plugin has: %s\n", testString); + fclose (f); + return FALSE; + } + } else if (length != 0) { + printf ("Effect name mismatch! Plugin has none.\n", testString); + fclose (f); + return FALSE; + } + + fread (&length, sizeof (unsigned), 1, f); + length = htonl (length); + fread (vendorString, length, 1, f); + vendorString[length] = 0; + printf ("Vendor string: %s\n", vendorString); + + success = fst_call_dispatcher( fst, effGetVendorString, 0, 0, testString, 0 ); + if (success == 1) { + if (strcmp (testString, vendorString) != 0) { + printf ("Vendor string mismatch! Plugin has: %s\n", testString); + fclose (f); + return FALSE; + } + } else if (length != 0) { + printf ("Vendor string mismatch! Plugin has none.\n", testString); + fclose (f); + return FALSE; + } + + int numParam; + unsigned i; + fread (&numParam, sizeof (int), 1, f); + numParam = htonl (numParam); + for (i = 0; i < numParam; ++i) { + float val; + fread (&val, sizeof (float), 1, f); + val = htonf (val); + + pthread_mutex_lock( &fst->lock ); + fst->plugin->setParameter( fst->plugin, i, val ); + pthread_mutex_unlock( &fst->lock ); + } + + int bytelen; + fread (&bytelen, sizeof (int), 1, f); + bytelen = htonl (bytelen); + if (bytelen) { + char * buf = malloc (bytelen); + fread (buf, bytelen, 1, f); + + fst_call_dispatcher( fst, 24, 0, bytelen, buf, 0 ); + free (buf); + } + } else { + printf ("Could not open state file\n"); + return FALSE; + } + return TRUE; + +} +#endif + +int fst_save_state (FST * fst, char * filename) +{ + FILE * f = fopen (filename, "wb"); + if (f) { + int bytelen; + int numParams = fst->plugin->numParams; + unsigned i; + char productString[64]; + char effectName[64]; + char vendorString[64]; + int success; + unsigned length; + + // write header + fprintf( f, "\n" ); + + success = fst_call_dispatcher( fst, effGetProductString, 0, 0, productString, 0 ); + if( success == 1 ) { + fprintf (f, " \n", productString); + } else { + printf ("No product string\n"); + } + + success = fst_call_dispatcher( fst, effGetEffectName, 0, 0, effectName, 0 ); + if( success == 1 ) { + fprintf (f, " \n", effectName); + printf ("Effect name: %s\n", effectName); + } else { + printf ("No effect name\n"); + } + + success = fst_call_dispatcher( fst, effGetVendorString, 0, 0, vendorString, 0 ); + if( success == 1 ) { + fprintf (f, " \n", vendorString); + printf ("Vendor string: %s\n", vendorString); + } else { + printf ("No vendor string\n"); + } + + + if( fst->plugin->flags & 32 ) { + numParams = 0; + } + + for( i=0; ilock ); + val = fst->plugin->getParameter( fst->plugin, i ); + pthread_mutex_unlock( &fst->lock ); + fprintf( f, " \n", i, val ); + } + + if( fst->plugin->flags & 32 ) { + printf( "getting chunk...\n" ); + void * chunk; + bytelen = fst_call_dispatcher( fst, 23, 0, 0, &chunk, 0 ); + printf( "got tha chunk..\n" ); + if( bytelen ) { + if( bytelen < 0 ) { + printf( "Chunke len < 0 !!! Not saving chunk.\n" ); + } else { + char *encoded = g_base64_encode( chunk, bytelen ); + fprintf( f, " \n %s\n \n", bytelen, encoded ); + g_free( encoded ); + } + } + } + + fprintf( f, "\n" ); + fclose( f ); + } else { + printf ("Could not open state file\n"); + return FALSE; + } + return TRUE; +} + -- cgit v1.2.3