diff --git a/SConstruct b/SConstruct index 2d4651994d..825fa2a5d2 100644 --- a/SConstruct +++ b/SConstruct @@ -417,28 +417,6 @@ tarball_bld = Builder (action = tarballer, env.Append (BUILDERS = {'Distribute' : dist_bld}) env.Append (BUILDERS = {'Tarball' : tarball_bld}) -# -# Make sure they know what they are doing -# - -if env['VST']: - if os.path.isfile('.personal_use_only'): - print "Enabling VST support. Note that distributing a VST-enabled ardour\nis a violation of several different licences.\nBuild with VST=false if you intend to distribute ardour to others." - else: - sys.stdout.write ("Are you building Ardour for personal use (rather than distribution to others)? [no]: ") - answer = sys.stdin.readline () - answer = answer.rstrip().strip() - if answer == "yes" or answer == "y": - fh = open('.personal_use_only', 'w') - fh.close() - print "OK, VST support will be enabled" - else: - print 'You cannot build Ardour with VST support for distribution to others.\nIt is a violation of several different licenses. Build with VST=false.' - sys.exit (-1); -else: - if os.path.isfile('.personal_use_only'): - os.remove('.personal_use_only') - #################### # push environment #################### diff --git a/gtk2_ardour/main.cc b/gtk2_ardour/main.cc index 6861b178d1..32454d69d5 100644 --- a/gtk2_ardour/main.cc +++ b/gtk2_ardour/main.cc @@ -288,6 +288,9 @@ sigpipe_handler (int sig) } #ifdef VST_SUPPORT + +extern int gui_init (int* argc, char** argv[]); + /* this is called from the entry point of a wine-compiled executable that is linked against gtk2_ardour built as a shared library. @@ -307,6 +310,13 @@ int main (int argc, char *argv[]) Glib::thread_init(); gtk_set_locale (); +#ifdef VST_SUPPORT + /* this does some magic that is needed to make GTK and Wine's own + X11 client interact properly. + */ + gui_init (&argc, &argv); +#endif + (void) bindtextdomain (PACKAGE, localedir); /* our i18n translations are all in UTF-8, so make sure that even if the user locale doesn't specify UTF-8, diff --git a/gtk2_ardour/vst_pluginui.cc b/gtk2_ardour/vst_pluginui.cc index 299c2f5681..0ee7956f53 100644 --- a/gtk2_ardour/vst_pluginui.cc +++ b/gtk2_ardour/vst_pluginui.cc @@ -18,6 +18,7 @@ */ #include +#include #include #include "ardour/processor.h" #include "ardour/vst_plugin.h" @@ -76,6 +77,8 @@ VSTPluginUI::package (Gtk::Window& win) socket.add_id (fst_get_XID (vst->fst())); + fst_move_window_into_view (vst->fst()); + return 0; } @@ -118,3 +121,28 @@ VSTPluginUI::configure_handler (GdkEventConfigure* ev, Gtk::Socket *socket) return false; } +typedef int (*error_handler_t)( Display *, XErrorEvent *); +static Display *the_gtk_display; +static error_handler_t wine_error_handler; +static error_handler_t gtk_error_handler; + +static int +fst_xerror_handler( Display *disp, XErrorEvent *ev ) +{ + if (disp == the_gtk_display) { + printf ("relaying error to gtk\n"); + return gtk_error_handler (disp, ev); + } else { + printf( "relaying error to wine\n" ); + return wine_error_handler (disp, ev); + } +} + +void +gui_init (int *argc, char **argv[]) +{ + wine_error_handler = XSetErrorHandler (NULL); + gtk_init (argc, argv); + the_gtk_display = gdk_x11_display_get_xdisplay (gdk_display_get_default()); + gtk_error_handler = XSetErrorHandler( fst_xerror_handler ); +} diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 3d2c4b7e9d..19e6c27ba4 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -41,9 +41,6 @@ #include "ardour/utils.h" #include "ardour/event_type_map.h" #include "ardour/io.h" -#ifdef VST_SUPPORT -#include -#endif #include "ardour/timestamps.h" diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index b1b934c43f..594b4fcd48 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -315,7 +315,7 @@ ARDOUR::init (bool use_vst, bool try_optimization) #ifdef VST_SUPPORT - if (Config->get_use_vst() && fst_init ()) { + if (Config->get_use_vst() && fst_init (0)) { return -1; } #endif diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc index bf62412700..c665c72126 100644 --- a/libs/ardour/plugin_manager.cc +++ b/libs/ardour/plugin_manager.cc @@ -526,7 +526,7 @@ PluginManager::vst_discover (string path) info->unique_id = buf; info->category = "VST"; info->path = path; - // need to set info->creator but FST doesn't provide it + info->creator = finfo->creator; info->index = 0; info->n_inputs = finfo->numInputs; info->n_outputs = finfo->numOutputs; diff --git a/libs/ardour/session_vst.cc b/libs/ardour/session_vst.cc index 89fb2a8397..86b541f467 100644 --- a/libs/ardour/session_vst.cc +++ b/libs/ardour/session_vst.cc @@ -52,7 +52,7 @@ long Session::vst_callback (AEffect* effect, SHOW_CALLBACK ("am callback, opcode = %d", opcode); if (effect && effect->user) { - plug = static_cast (effect->user); + plug = (VSTPlugin*) (effect->user); session = &plug->session(); } else { plug = 0; diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc index 242d9ecfdb..cd2531d522 100644 --- a/libs/ardour/vst_plugin.cc +++ b/libs/ardour/vst_plugin.cc @@ -146,14 +146,14 @@ VSTPlugin::get_state() XMLNode *root = new XMLNode (state_node_name()); LocaleGuard lg (X_("POSIX")); - if (_plugin->flags & effFlagsProgramChunks) { + if (_plugin->flags & 32 /* effFlagsProgramsChunks */) { /* fetch the current chunk */ void* data; long data_size; - if ((data_size = _plugin->dispatcher (_plugin, effGetChunk, 0, 0, &data, false)) == 0) { + if ((data_size = _plugin->dispatcher (_plugin, 23 /* effGetChunk */, 0, 0, &data, false)) == 0) { return *root; } @@ -262,6 +262,8 @@ VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) if (_plugin->dispatcher (_plugin, effGetParameterProperties, which, 0, &prop, 0)) { +#ifdef VESTIGE_COMPLETE + /* i have yet to find or hear of a VST plugin that uses this */ if (prop.flags & kVstParameterUsesIntegerMinMax) { @@ -297,6 +299,7 @@ VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) desc.logarithmic = false; desc.sr_dependent = false; desc.label = prop.label; +#endif } else { @@ -325,7 +328,7 @@ VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) bool VSTPlugin::load_preset (string name) { - if (_plugin->flags & effFlagsProgramChunks) { + if (_plugin->flags & 32 /* effFlagsProgramsChunks */) { error << _("no support for presets using chunks at this time") << endmsg; return false; @@ -336,7 +339,7 @@ VSTPlugin::load_preset (string name) bool VSTPlugin::save_preset (string name) { - if (_plugin->flags & effFlagsProgramChunks) { + if (_plugin->flags & 32 /* effFlagsProgramsChunks */) { error << _("no support for presets using chunks at this time") << endmsg; return false; @@ -359,7 +362,11 @@ VSTPlugin::signal_latency () const return _user_latency; } - return _plugin->initialDelay; +#ifdef VESTIGE_HEADER + return *((nframes_t *) (((char *) &_plugin->flags) + 12)); /* initialDelay */ +#else + return _plugin->initial_delay; +#endif } set @@ -424,8 +431,13 @@ string VSTPlugin::unique_id() const { char buf[32]; - snprintf (buf, sizeof (buf), "%d", _plugin->uniqueID); - return string (buf); + +#ifdef VESTIGE_HEADER + snprintf (buf, sizeof (buf), "%d", *((int32_t*) &_plugin->unused_id)); +#else + snprintf (buf, sizeof (buf), "%d", _plugin->uniqueID); +#endif + return string (buf); } diff --git a/libs/evoral/evoral/ControlList.hpp b/libs/evoral/evoral/ControlList.hpp index c9f791ec17..ce5a98261b 100644 --- a/libs/evoral/evoral/ControlList.hpp +++ b/libs/evoral/evoral/ControlList.hpp @@ -19,6 +19,7 @@ #ifndef EVORAL_CONTROL_LIST_HPP #define EVORAL_CONTROL_LIST_HPP +#include #include #include #include diff --git a/libs/fst/SConscript b/libs/fst/SConscript index 576283d73c..92c7504257 100644 --- a/libs/fst/SConscript +++ b/libs/fst/SConscript @@ -7,46 +7,18 @@ import glob fst_src = glob.glob('*.c') -Import('env install_prefix') +Import('env install_prefix libraries') fst = env.Clone(CC="winegcc") fst.Append (CPPPATH=".") +fst.Merge ([libraries['glib2']]) if fst['VST']: - vst_dir = Dir ('libs/vst') - vst_sdk_dir = Dir ('vstsdk2.3') - # - # if it exists, try to use the Steinberg zip package - # - vst_sdk_zip = File ('vstsdk2.3.zip') - - if os.access (vst_sdk_zip.abspath, os.F_OK): - print 'VST package discovered.' - elif os.access ('vst_sdk2_3.zip', os.F_OK): - # - # add a build target that unpacks the zip package the Steinberg "meta" zip package - # - vst_meta_zip = fst.Command (vst_sdk_zip, 'vst_sdk2_3.zip', "unzip -o -d ${TARGET.dir} $SOURCES vstsdk2.3.zip" ) - print 'VST meta-package discovered.' - else: - if os.access ('vstsdk2.3.zip', os.F_OK) != 1: - print 'Did not find vst_sdk2_3.zip or vstsdk2.3.zip in libs/fst.' - print 'Make sure the correct file is in the correct location and correctly named.' - print 'Please see http://ardour.org/building_vst_support for more information.' - sys.exit (1) - - vst_headers = fst.Command ([ 'vst/aeffectx.h', 'vst/AEffect.h' ], vst_sdk_zip, [ - "unzip -qq -d ${SOURCE.dir} -o $SOURCE", - Delete ('$TARGET.dir'), - Copy ('${TARGET.dir}', 'libs/fst/vstsdk2.3/source/common'), - "sed -i '/struct VstFileType\|struct VstFileSelect/,/};/d' $TARGET" - ]) - a = fst.Object ('fst', 'fst.c') b = fst.Object ('fstinfofile', 'fstinfofile.c') c = fst.Object ('vstwin', 'vstwin.c') d = fst.Object ('vsti', 'vsti.c') - Default([vst_headers,a,b,c,d]) + Default([a,b,c,d]) env.Alias('tarball', env.Distribute (env['DISTTREE'], fst_src + ['SConscript', diff --git a/libs/fst/fst.c b/libs/fst/fst.c index 85473578d2..cbee5de52a 100644 --- a/libs/fst/fst.c +++ b/libs/fst/fst.c @@ -3,15 +3,6 @@ #include "fst.h" - -void -default_fst_error_callback (const char *desc) -{ - fprintf(stderr, "%s\n", desc); -} - -void (*fst_error_callback)(const char *desc) = &default_fst_error_callback; - void fst_error (const char *fmt, ...) { @@ -24,4 +15,10 @@ fst_error (const char *fmt, ...) va_end (ap); } +void +default_fst_error_callback (const char *desc) +{ + fprintf(stderr, "%s\n", desc); +} +void (*fst_error_callback)(const char *desc) = &default_fst_error_callback; diff --git a/libs/fst/fst.h b/libs/fst/fst.h index 493cb2e572..2a0130667a 100644 --- a/libs/fst/fst.h +++ b/libs/fst/fst.h @@ -8,22 +8,28 @@ /** * Display FST error message. * - * @param fmt printf-style formatting specification + * Set via fst_set_error_function(), otherwise a FST-provided + * default will print @a msg (plus a newline) to stderr. + * + * @param msg error message text (no newline at end). */ -extern void fst_error (const char *fmt, ...); +extern void (*fst_error_callback)(const char *msg); /** * Set the @ref fst_error_callback for error message display. * * The FST library provides two built-in callbacks for this purpose: - * default_fst_error_callback(). - * - * The default will print the message (plus a newline) to stderr. - * + * default_fst_error_callback() and silent_fst_error_callback(). */ void fst_set_error_function (void (*func)(const char *)); -#include +void fst_error (const char *fmt, ...); + +#define VESTIGE_HEADER + +#ifdef VESTIGE_HEADER +#include +#endif typedef struct _FST FST; typedef struct _FSTHandle FSTHandle; @@ -32,6 +38,7 @@ typedef struct _FSTInfo FSTInfo; struct _FSTInfo { char *name; + char *creator; int UniqueID; char *Category; @@ -50,30 +57,46 @@ struct _FSTInfo char **ParamLabels; }; +typedef struct AEffect * (*main_entry_t)(audioMasterCallback); + struct _FSTHandle { void* dll; char* name; char* nameptr; /* ptr returned from strdup() etc. */ - AEffect* (*main_entry)(audioMasterCallback); + //struct AEffect* (*main_entry)(audioMasterCallback); + main_entry_t main_entry; int plugincnt; }; struct _FST { - AEffect* plugin; + struct AEffect* plugin; void* window; /* win32 HWND */ int xid; /* X11 XWindow */ FSTHandle* handle; int width; int height; + int wantIdle; int destroy; - struct _FST* next; + int want_program; + float *want_params; + float *set_params; + int dispatcher_wantcall; + int dispatcher_opcode; + int dispatcher_index; + int dispatcher_val; + void * dispatcher_ptr; + float dispatcher_opt; + int dispatcher_retval; + + struct _FST* next; pthread_mutex_t lock; pthread_cond_t window_status_change; + pthread_cond_t plugin_dispatcher_called; int been_activated; }; @@ -81,8 +104,7 @@ struct _FST extern "C" { #endif -extern int fst_init (); -extern void fst_finish (); +extern int fst_init (void* possible_hmodule); extern FSTHandle* fst_load (const char*); extern int fst_unload (FSTHandle*); @@ -90,17 +112,26 @@ extern int fst_unload (FSTHandle*); extern FST* fst_instantiate (FSTHandle*, audioMasterCallback amc, void* userptr); extern void fst_close (FST*); -extern void fst_event_loop_remove_plugin (FST* fst); -extern void fst_event_loop_add_plugin (FST* fst); - +extern int fst_create_editor (FST* fst); extern int fst_run_editor (FST*); extern void fst_destroy_editor (FST*); extern int fst_get_XID (FST*); +extern void fst_move_window_into_view (FST*); -extern void fst_signal_handler (int sig, siginfo_t* info, void* context); +extern FSTInfo *fst_get_info (char *dllpathname); +extern void fst_free_info (FSTInfo *info); +extern void fst_event_loop_remove_plugin (FST* fst); +extern int fst_call_dispatcher(FST *fst, int opcode, int index, int val, void *ptr, float opt ); -extern FSTInfo *fst_get_info( char *dllpathname ); -extern void fst_free_info( FSTInfo *info ); +/** + * Load a plugin state from a file. + */ +extern int fst_load_state (FST * fst, char * filename); + +/** + * Save a plugin state to a file. + */ +extern int fst_save_state (FST * fst, char * filename); #ifdef __cplusplus } diff --git a/libs/fst/fstinfofile.c b/libs/fst/fstinfofile.c index 7b0c69d015..2d7fb2fa6a 100644 --- a/libs/fst/fstinfofile.c +++ b/libs/fst/fstinfofile.c @@ -1,15 +1,13 @@ - #include "fst.h" -#include "vst/aeffectx.h" #include #include #include +#include #include #include #include -#include #define MAX_STRING_LEN 256 @@ -49,6 +47,7 @@ static FSTInfo *load_fst_info_file( char *filename ) { } if( (info->name = read_string( fp )) == NULL ) goto error; + if( (info->creator = read_string( fp )) == NULL ) goto error; if( 1 != fscanf( fp, "%d\n", &info->UniqueID ) ) goto error; if( (info->Category = read_string( fp )) == NULL ) goto error; if( 1 != fscanf( fp, "%d\n", &info->numInputs ) ) goto error; @@ -96,6 +95,7 @@ static int save_fst_info_file( FSTInfo *info, char *filename ) { } fprintf( fp, "%s\n", info->name ); + fprintf( fp, "%s\n", info->creator ); fprintf( fp, "%d\n", info->UniqueID ); fprintf( fp, "%s\n", info->Category ); fprintf( fp, "%d\n", info->numInputs ); @@ -123,7 +123,7 @@ static char *fst_dllpath_to_infopath( char *dllpath ) { if( strstr( dllpath, ".dll" ) == NULL ) return NULL; retval = strdup( dllpath ); - sprintf( retval + strlen(retval) - 4, ".fst" ); + sprintf( retval + strlen(retval) - 4, ".fsi" ); return retval; } @@ -144,7 +144,7 @@ static int fst_info_file_is_valid( char *dllpath ) { } static int fst_can_midi( FST *fst ) { - AEffect *plugin = fst->plugin; + struct AEffect *plugin = fst->plugin; int vst_version = plugin->dispatcher (plugin, effGetVstVersion, 0, 0, NULL, 0.0f); if (vst_version >= 2) { @@ -160,8 +160,9 @@ static int fst_can_midi( FST *fst ) { } static FSTInfo *fst_info_from_plugin( FST *fst ) { FSTInfo *info = (FSTInfo *) malloc( sizeof( FSTInfo ) ); - AEffect *plugin; + struct AEffect *plugin; int i; + char creator[65]; if( ! fst ) { fst_error( "fst is NULL\n" ); @@ -174,7 +175,19 @@ static FSTInfo *fst_info_from_plugin( FST *fst ) { info->name = strdup(fst->handle->name ); + plugin->dispatcher (plugin, 47 /* effGetVendorString */, 0, 0, creator, 0); + if (strlen (creator) == 0) { + info->creator = strdup ("Unknown"); + } else { + info->creator = strdup (creator); + } + +#ifdef VESTIGE_HEADER + info->UniqueID = *((int32_t *) &plugin->unused_id); +#else info->UniqueID = plugin->uniqueID; +#endif + info->Category = strdup( "None" ); // FIXME: info->numInputs = plugin->numInputs; info->numOutputs = plugin->numOutputs; @@ -188,22 +201,20 @@ static FSTInfo *fst_info_from_plugin( FST *fst ) { for( i=0; inumParams; i++ ) { char name[20]; char label[9]; - plugin->dispatcher (plugin, - effGetParamName, - i, 0, name, 0); - - plugin->dispatcher (plugin, - effGetParamLabel, - i, 0, label, 0); - + plugin->dispatcher (plugin, + effGetParamName, + i, 0, name, 0); info->ParamNames[i] = strdup( name ); + plugin->dispatcher (plugin, + 6 /* effGetParamLabel */, + i, 0, label, 0); info->ParamLabels[i] = strdup( label ); } return info; } // most simple one :) could be sufficient.... -static long simple_master_callback( AEffect *fx, long opcode, long index, long value, void *ptr, float opt ) { +static long simple_master_callback( struct AEffect *fx, long opcode, long index, long value, void *ptr, float opt ) { if( opcode == audioMasterVersion ) return 2; else @@ -227,9 +238,7 @@ FSTInfo *fst_get_info( char *dllpath ) { FSTInfo *info; char *fstpath; - if( !(h = fst_load( dllpath )) ) { - return NULL; - } + if( !(h = fst_load( dllpath )) ) return NULL; if( !(fst = fst_instantiate( h, simple_master_callback, NULL )) ) { fst_unload( h ); fst_error( "instantiate failed\n" ); @@ -261,6 +270,7 @@ void fst_free_info( FSTInfo *info ) { free( info->ParamLabels[i] ); } free( info->name ); + free( info->creator ); free( info->Category ); free( info ); } diff --git a/libs/fst/jackvst.h b/libs/fst/jackvst.h index abb9e22e12..31e34f55b9 100644 --- a/libs/fst/jackvst.h +++ b/libs/fst/jackvst.h @@ -1,8 +1,8 @@ #ifndef __jack_vst_h__ #define __jack_vst_h__ -#include -#include +#include +#include #include #include #include @@ -16,15 +16,24 @@ struct _JackVST { FST* fst; float **ins; float **outs; + jack_port_t *midi_port; jack_port_t **inports; jack_port_t **outports; void* userdata; int bypassed; int muted; + int current_program; + + int midi_map[128]; + volatile int midi_learn; + volatile int midi_learn_CC; + volatile int midi_learn_PARAM; int resume_called; + /* For VST/i support */ + int want_midi; pthread_t midi_thread; snd_seq_t* seq; int midiquit; @@ -32,4 +41,6 @@ struct _JackVST { struct VstEvents* events; }; +#define MIDI_EVENT_MAX 1024 + #endif /* __jack_vst_h__ */ diff --git a/libs/fst/vestige/aeffectx.h b/libs/fst/vestige/aeffectx.h new file mode 100644 index 0000000000..790c93e6dc --- /dev/null +++ b/libs/fst/vestige/aeffectx.h @@ -0,0 +1,288 @@ +/* + * aeffectx.h - simple header to allow VeSTige compilation and eventually work + * + * Copyright (c) 2006 Javier Serrano Polo + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#ifndef _AEFFECTX_H +#define _AEFFECTX_H + + +#define audioMasterAutomate 0 +#define audioMasterVersion 1 +#define audioMasterCurrentId 2 +#define audioMasterIdle 3 +#define audioMasterPinConnected 4 +// unsupported? 5 +#define audioMasterWantMidi 6 +#define audioMasterGetTime 7 +#define audioMasterProcessEvents 8 +#define audioMasterSetTime 9 +#define audioMasterTempoAt 10 +#define audioMasterGetNumAutomatableParameters 11 +#define audioMasterGetParameterQuantization 12 +#define audioMasterIOChanged 13 +#define audioMasterNeedIdle 14 +#define audioMasterSizeWindow 15 +#define audioMasterGetSampleRate 16 +#define audioMasterGetBlockSize 17 +#define audioMasterGetInputLatency 18 +#define audioMasterGetOutputLatency 19 +#define audioMasterGetPreviousPlug 20 +#define audioMasterGetNextPlug 21 +#define audioMasterWillReplaceOrAccumulate 22 +#define audioMasterGetCurrentProcessLevel 23 +#define audioMasterGetAutomationState 24 +#define audioMasterOfflineStart 25 +#define audioMasterOfflineRead 26 +#define audioMasterOfflineWrite 27 +#define audioMasterOfflineGetCurrentPass 28 +#define audioMasterOfflineGetCurrentMetaPass 29 +#define audioMasterSetOutputSampleRate 30 +// unsupported? 31 +#define audioMasterGetSpeakerArrangement 31 // deprecated in 2.4? +#define audioMasterGetVendorString 32 +#define audioMasterGetProductString 33 +#define audioMasterGetVendorVersion 34 +#define audioMasterVendorSpecific 35 +#define audioMasterSetIcon 36 +#define audioMasterCanDo 37 +#define audioMasterGetLanguage 38 +#define audioMasterOpenWindow 39 +#define audioMasterCloseWindow 40 +#define audioMasterGetDirectory 41 +#define audioMasterUpdateDisplay 42 +#define audioMasterBeginEdit 43 +#define audioMasterEndEdit 44 +#define audioMasterOpenFileSelector 45 +#define audioMasterCloseFileSelector 46// currently unused +#define audioMasterEditFile 47// currently unused +#define audioMasterGetChunkFile 48// currently unused +#define audioMasterGetInputSpeakerArrangement 49 // currently unused + +#define effFlagsHasEditor 1 +// very likely +#define effFlagsCanReplacing (1 << 4) +// currently unused +#define effFlagsIsSynth (1 << 8) + +#define effOpen 0 +//currently unused +#define effClose 1 +// currently unused +#define effSetProgram 2 +// currently unused +#define effGetProgram 3 +// currently unused +#define effGetProgramName 5 +#define effGetParamLabel 6 +// currently unused +#define effGetParamName 8 +// this is a guess +#define effSetSampleRate 10 +#define effSetBlockSize 11 +#define effMainsChanged 12 +#define effEditGetRect 13 +#define effEditOpen 14 +#define effEditClose 15 +#define effEditIdle 19 +#define effProcessEvents 25 +#define effGetEffectName 45 +// missing +#define effGetParameterProperties 47 +#define effGetVendorString 47 +#define effGetProductString 48 +#define effGetVendorVersion 49 +// currently unused +#define effCanDo 51 +// currently unused +#define effGetVstVersion 58 + +#ifdef WORDS_BIGENDIAN +// "VstP" +#define kEffectMagic 0x50747356 +#else +// "PtsV" +#define kEffectMagic 0x56737450 +#endif + +#define kVstLangEnglish 1 +#define kVstMidiType 1 +#define kVstTransportPlaying (1 << 1) +#define kVstParameterUsesFloatStep (1 << 2) +#define kVstTempoValid (1 << 10) +#define kVstBarsValid (1 << 11) +#define kVstTransportChanged 1 + +typedef struct VstMidiEvent +{ + // 00 + int type; + // 04 + int byteSize; + // 08 + int deltaFrames; + // 0c? + int flags; + // 10? + int noteLength; + // 14? + int noteOffset; + // 18 + char midiData[4]; + // 1c? + char detune; + // 1d? + char noteOffVelocity; + // 1e? + char reserved1; + // 1f? + char reserved2; + +} VstMidiEvent; + + + + +typedef struct VstEvent +{ + char dump[sizeof( VstMidiEvent )]; + +} VstEvent ; + + + + +typedef struct VstEvents +{ + // 00 + int numEvents; + // 04 + int reserved; + // 08 + VstEvent * events[]; +} VstEvents; + + + + +// Not finished, neither really used +typedef struct VstParameterProperties +{ + float stepFloat; + char label[64]; + int flags; + int minInteger; + int maxInteger; + int stepInteger; + char shortLabel[8]; + int category; + char categoryLabel[24]; + char empty[128]; + +} VstParameterProperties; + + + + +typedef struct AEffect +{ + // Never use c++!!! + // 00-03 + int magic; + // dispatcher 04-07 + int (* dispatcher)( struct AEffect * , int , int , int , void * , float ); + // process, quite sure 08-0b + void (* process)( struct AEffect * , float * * , float * * , int ); + // setParameter 0c-0f + void (* setParameter)( struct AEffect * , int , float ); + // getParameter 10-13 + float (* getParameter)( struct AEffect * , int ); + // programs 14-17 + int numPrograms; + // Params 18-1b + int numParams; + // Input 1c-1f + int numInputs; + // Output 20-23 + int numOutputs; + // flags 24-27 + int flags; + // Fill somewhere 28-2b + void * user; + // Zeroes 2c-2f 30-33 34-37 38-3b + char empty3[4 + 4 + 4 + 4]; + // 1.0f 3c-3f + float unkown_float; + // An object? pointer 40-43 + char empty4[4]; + // Zeroes 44-47 + char empty5[4]; + // Id 48-4b + char unused_id[4]; + // Don't know 4c-4f + char unknown1[4]; + // processReplacing 50-53 + void (* processReplacing)( struct AEffect * , float * * , float * * , int ); + + int uniqueID; + +} AEffect; + + + + +typedef struct VstTimeInfo +{ + // 00 + double samplePos; + // 08 + double sampleRate; + // unconfirmed 10 18 + char empty1[8 + 8]; + // 20? + double tempo; + // unconfirmed 28 30 38 + char empty2[8 + 8 + 8]; + // 40? + int timeSigNumerator; + // 44? + int timeSigDenominator; + // unconfirmed 48 4c 50 + char empty3[4 + 4 + 4]; + // 54 + int flags; + +} VstTimeInfo; + + + + +typedef long int (* audioMasterCallback)( AEffect * , long int , long int , + long int , void * , float ); +// we don't use it, may be noise +#define VSTCALLBACK + + + + +#endif diff --git a/libs/fst/vsti.c b/libs/fst/vsti.c index f6d8725ddf..6a64f9c5e4 100644 --- a/libs/fst/vsti.c +++ b/libs/fst/vsti.c @@ -30,7 +30,9 @@ #include #include #include -#include +#include +#include +#include snd_seq_t * create_sequencer (const char* client_name, bool isinput) @@ -74,7 +76,7 @@ queue_midi (JackVST *jvst, int val1, int val2, int val3) return; } - pevent = (struct VstMidiEevent *) vec[0].buf; + pevent = (struct VstMidiEvent *) vec[0].buf; // printf("note: %d\n",note); @@ -104,6 +106,13 @@ void *midireceiver(void *arg) JackVST *jvst = (JackVST* )arg; int val; + struct sched_param scp; + scp.sched_priority = 50; + + // Try to set fifo priority... + // this works, if we are root or newe sched-cap manegment is used... + pthread_setschedparam( pthread_self(), SCHED_FIFO, &scp ); + while (1) { snd_seq_event_input (jvst->seq, &event); 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"; +extern boolean g_quit; - case 0x0001: - return "WM_CREATE"; - case 0x0002: - return "WM_DESTROY"; - case 0x0003: - return "WM_MOVE"; - case 0x0004: - return "WM_SIZEWAIT"; +#define DELAYED_WINDOW 1 - 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"; - - case 0x0013: - return "WM_QUERYOPEN"; - - case 0x0014: - return "WM_ERASEBKGND"; - - case 0x0015: - return "WM_SYSCOLORCHANGE"; - - case 0x0016: - return "WM_ENDSESSION"; - - 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,11 +110,218 @@ fst_handle_new () return fst; } +DWORD WINAPI gui_event_loop (LPVOID param) +{ + MSG msg; + FST* fst; + char c; + HMODULE hInst; + HWND window; + + gui_thread_id = GetCurrentThreadId (); + + /* create a dummy window for timer events */ + + if ((hInst = GetModuleHandleA (NULL)) == NULL) { + fst_error ("can't get module handle"); + return 1; + } + + if ((window = CreateWindowExA (0, "FST", "dummy", + WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX, + 9999, 9999, + 1, 1, + NULL, NULL, + hInst, + NULL )) == NULL) { + fst_error ("cannot create dummy timer window"); + } + + if (!SetTimer (window, 1000, 20, NULL)) { + fst_error ("cannot set timer on dummy window"); + } + + while (GetMessageA (&msg, NULL, 0,0)) { + TranslateMessage( &msg ); + DispatchMessageA (&msg); + + /* handle window creation requests, destroy requests, + and run idle callbacks + */ + + if( msg.message == WM_TIMER ) { + pthread_mutex_lock (&plugin_mutex); +again: + for (fst = fst_first; fst; fst = fst->next) { + + if (fst->destroy) { + if (fst->window) { + fst->plugin->dispatcher( fst->plugin, effEditClose, 0, 0, NULL, 0.0 ); + CloseWindow (fst->window); + fst->window = NULL; + fst->destroy = FALSE; + } + fst_event_loop_remove_plugin (fst); + fst->been_activated = FALSE; + pthread_mutex_lock (&fst->lock); + pthread_cond_signal (&fst->window_status_change); + pthread_mutex_unlock (&fst->lock); + goto 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); + pthread_cond_signal (&fst->window_status_change); + pthread_mutex_unlock (&fst->lock); + goto again; + } + /* 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); + } + } + fprintf (stderr, "VST GUI EVENT LOOP THREAD EXIT\n"); + return 0; +} + +int +fst_init (void* possible_hmodule) +{ + WNDCLASSEX wclass; + HMODULE hInst; + + 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; + wc.cbWndExtra = 0; + wc.hInstance = hInst; + wc.hIcon = LoadIconA( hInst, "FST"); + wc.hCursor = LoadCursorA( NULL, IDI_APPLICATION ); + wc.hbrBackground = GetStockObject( BLACK_BRUSH ); + wc.lpszMenuName = "FSTMENU"; + wc.lpszClassName = "FST"; + //wc.hIconSm = 0; +#endif + + 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; +} + +int +fst_run_editor (FST* fst) +{ + pthread_mutex_lock (&plugin_mutex); + + if (fst_first == NULL) { + fst_first = fst; + } else { + FST* p = fst_first; + while (p->next) { + p = p->next; + } + p->next = fst; + } + + pthread_mutex_unlock (&plugin_mutex); + + /* wait for the plugin editor window to be created (or not) */ + + pthread_mutex_lock (&fst->lock); + if (!fst->window) { + pthread_cond_wait (&fst->window_status_change, &fst->lock); + } + pthread_mutex_unlock (&fst->lock); + + if (!fst->window) { + 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 */ @@ -227,7 +340,9 @@ fst_create_editor (FST* fst) // 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, +// (WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX), + 9999,9999,1,1, +// CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL)) == NULL) { @@ -240,34 +355,54 @@ fst_create_editor (FST* fst) } fst->window = window; - fst->xid = (int) GetPropA (window, "__wine_x11_whole_window"); +// fst->xid = (int) GetPropA (window, "__wine_x11_whole_window"); - { - struct ERect* er; - ShowWindow (fst->window, SW_SHOW); + //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->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); - } + 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)) { - fst_error ("could not post message to gui thread"); - } + //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); } @@ -294,180 +429,59 @@ fst_event_loop_remove_plugin (FST* fst) } -void debreak( void ) { printf( "debreak\n" ); } - -DWORD WINAPI gui_event_loop (LPVOID param) +HMODULE +fst_load_vst_library(const char * path) { - MSG msg; - FST* fst; - HMODULE hInst; - HWND window; + HMODULE dll; + char * full_path; + char * envdup; + char * vst_path; + size_t len1; + size_t len2; - gui_thread_id = GetCurrentThreadId (); - - /* create a dummy window for timer events */ - - if ((hInst = GetModuleHandleA (NULL)) == NULL) { - fst_error ("can't get module handle"); - return 1; - } - - if ((window = CreateWindowExA (0, "FST", "dummy", - WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX, - CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, CW_USEDEFAULT, - NULL, NULL, - hInst, - NULL )) == NULL) { - fst_error ("cannot create dummy timer window"); + if ((dll = LoadLibraryA (path)) != NULL) { + return dll; } - if (!SetTimer (window, 1000, 100, NULL)) { - fst_error ("cannot set timer on dummy window"); + envdup = getenv ("VST_PATH"); + if (envdup == NULL) { + return NULL; } - while (1) { + envdup = strdup (envdup); + if (envdup == NULL) { + fst_error ("strdup failed"); + return NULL; + } - GetMessageA (&msg, NULL, 0,0); + len2 = strlen(path); - if (msg.message == WM_SYSTEMERROR) { - /* sent when this thread is supposed to exist */ + 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; } - - if (msg.message == WM_KEYDOWN) debreak(); - TranslateMessage( &msg ); - DispatchMessageA (&msg); - - /* handle window creation requests, destroy requests, - and run idle callbacks - */ - - if( msg.message == WM_TIMER ) { - pthread_mutex_lock (&plugin_mutex); -again: - for (fst = fst_first; fst; fst = fst->next) { - - if (fst->destroy) { - if (fst->window) { - fst->plugin->dispatcher( fst->plugin, effEditClose, 0, 0, NULL, 0.0 ); - CloseWindow (fst->window); - fst->window = NULL; - fst->destroy = FALSE; - } - fst_event_loop_remove_plugin (fst); - fst->been_activated = FALSE; - pthread_mutex_lock (&fst->lock); - pthread_cond_signal (&fst->window_status_change); - pthread_mutex_unlock (&fst->lock); - goto again; - } - - if (fst->window == NULL) { - pthread_mutex_lock (&fst->lock); - if (fst_create_editor (fst)) { - fst_error ("cannot create editor for plugin %s", fst->handle->name); - fst_event_loop_remove_plugin (fst); - pthread_cond_signal (&fst->window_status_change); - pthread_mutex_unlock (&fst->lock); - goto again; - } - /* condition/unlock handled when we receive WM_ACTIVATE */ - } - - fst->plugin->dispatcher (fst->plugin, effEditIdle, 0, 0, NULL, 0); - } - pthread_mutex_unlock (&plugin_mutex); - } - } - fst_error ("FST GUI event loop has quit!"); - return 0; -} - -int -fst_init () -{ - WNDCLASSA wc; - HMODULE hInst; - - if ((hInst = GetModuleHandleA (NULL)) == NULL) { - fst_error ("can't get module handle"); - return -1; - } - wc.style = 0; - wc.lpfnWndProc = my_window_proc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInst; - wc.hIcon = LoadIconA( hInst, "FST"); - wc.hCursor = LoadCursorA( NULL, IDI_APPLICATION ); - wc.hbrBackground = GetStockObject( BLACK_BRUSH ); - wc.lpszMenuName = "MENU_FST"; - wc.lpszClassName = "FST"; - - if (!RegisterClassA(&wc)){ - return 1; + vst_path = strtok (NULL, ":"); } - if (CreateThread (NULL, 0, gui_event_loop, NULL, 0, NULL) == NULL) { - fst_error ("could not create new thread proxy"); - return -1; - } + free(envdup); - 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) { - fst_first = fst; - } else { - FST* p = fst_first; - while (p->next) { - p = p->next; - } - 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) */ - - pthread_mutex_lock (&fst->lock); - if (!fst->window) { - pthread_cond_wait (&fst->window_status_change, &fst->lock); - } - pthread_mutex_unlock (&fst->lock); - - if (!fst->window) { - fst_error ("no window created for VST plugin editor"); - return -1; - } - - return 0; + 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; +} + diff --git a/libs/sigc++2/missing b/libs/sigc++2/missing index 894e786e16..1c8ff7049d 100755 --- a/libs/sigc++2/missing +++ b/libs/sigc++2/missing @@ -1,9 +1,9 @@ #! /bin/sh # Common stub for a few missing GNU programs while installing. -scriptversion=2005-06-08.21 +scriptversion=2006-05-10.23 -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. @@ -33,6 +33,8 @@ if test $# -eq 0; then fi run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. @@ -44,7 +46,7 @@ fi msg="missing on your system" -case "$1" in +case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= @@ -77,6 +79,7 @@ Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c @@ -106,7 +109,7 @@ esac # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). -case "$1" in +case $1 in lex|yacc) # Not GNU programs, they don't have --version. ;; @@ -135,7 +138,7 @@ esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. -case "$1" in +case $1 in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if @@ -164,7 +167,7 @@ WARNING: \`$1' is $msg. You should only need it if test -z "$files" && files="config.h" touch_files= for f in $files; do - case "$f" in + case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; @@ -192,8 +195,8 @@ WARNING: \`$1' is needed, but is $msg. You can get \`$1' as part of \`Autoconf' from any GNU archive site." - file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` - test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else @@ -214,25 +217,25 @@ WARNING: \`$1' $msg. You should only need it if in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h - if [ $# -ne 1 ]; then + if test $# -ne 1; then eval LASTARG="\${$#}" - case "$LASTARG" in + case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if [ -f "$SRCFILE" ]; then + if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if [ -f "$SRCFILE" ]; then + if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi - if [ ! -f y.tab.h ]; then + if test ! -f y.tab.h; then echo >y.tab.h fi - if [ ! -f y.tab.c ]; then + if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; @@ -244,18 +247,18 @@ WARNING: \`$1' is $msg. You should only need it if in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c - if [ $# -ne 1 ]; then + if test $# -ne 1; then eval LASTARG="\${$#}" - case "$LASTARG" in + case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if [ -f "$SRCFILE" ]; then + if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi - if [ ! -f lex.yy.c ]; then + if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; @@ -267,11 +270,9 @@ WARNING: \`$1' is $msg. You should only need it if \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` - fi - if [ -f "$file" ]; then + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then touch $file else test -z "$file" || exec >$file @@ -289,11 +290,17 @@ WARNING: \`$1' is $msg. You should only need it if DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi @@ -317,13 +324,13 @@ WARNING: \`$1' is $msg. You should only need it if fi firstarg="$1" if shift; then - case "$firstarg" in + case $firstarg in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac - case "$firstarg" in + case $firstarg in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 diff --git a/vst/ardevst b/vst/ardevst index 39d9bdface..c040dbbacf 100755 --- a/vst/ardevst +++ b/vst/ardevst @@ -1,5 +1,6 @@ #!/bin/sh -export ARDOUR_PATH=../gtk2_ardour/icons:../gtk2_ardour/pixmaps:../gtk2_ardour -export LD_LIBRARY_PATH=../gtk2_ardour:../libs/surfaces/control_protocol:../libs/ardour:../libs/midi++2:../libs/pbd:../libs/soundtouch:../libs/gtkmm2ext:../libs/sigc++2:../libs/glibmm2:../libs/gtkmm2/atk:../libs/gtkmm2/pango:../libs/gtkmm2/gdk:../libs/gtkmm2/gtk:../libs/libgnomecanvasmm:../libs/libsndfile:../libs/appleutility:../libs/rubberband:../libs/vamp-sdk:$LD_LIBRARY_PATH -export GTK_PATH=$PWD/../libs/clearlooks:~/.ardour3 -exec wine ./ardour_vst.exe.so "$@" + +. ../gtk2_ardour/ardev_common.sh + +export LD_LIBRARY_PATH=gtk2_ardour:$LD_LIBRARY_PATH +exec wine ./vst/ardour_vst.exe.so "$@" diff --git a/vst/winmain.c b/vst/winmain.c index c2ad5fc6bd..0f9dff1360 100644 --- a/vst/winmain.c +++ b/vst/winmain.c @@ -1,17 +1,7 @@ -#include -#include -#include - extern int ardour_main(int argc, char* argv[]); int main (int argc, char* argv[]) { - // call the user specified main function - - int result = ardour_main(argc, argv); - printf ("main returned %d\n", result); - - return result; - + return ardour_main(argc, argv); }