13
0

FST code from 2.X branch

git-svn-id: svn://localhost/ardour2/branches/3.0@4981 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2009-04-16 00:43:41 +00:00
parent 54d9f2f2d8
commit c2b12f05f4
4 changed files with 253 additions and 186 deletions

View File

@ -8,21 +8,63 @@ import glob
fst_src = glob.glob('*.c') fst_src = glob.glob('*.c')
Import('env install_prefix libraries') Import('env install_prefix libraries')
fst = env.Clone(CC="winegcc") fst = env.Clone()
fst.Append (CPPPATH=".") fst.Append (CPPPATH=".")
fst.Merge ([libraries['glib2']]) fst.Merge ([
libraries['jack'],
libraries['glib2']
])
#
# See if JACK supports jack_set_thread_creator()
#
jack_test_source_file = """
#include <jack/jack.h>
#include <pthread.h>
int
my_pthread_create (pthread_t* thread_id, const pthread_attr_t* attr, void *(*function)(void*), void* arg)
{
return 0;
}
int main(int argc, char **argv)
{
jack_set_thread_creator (my_pthread_create);
return 0;
}
"""
def CheckJackSetThreadCreator(context):
context.Message('Checking for jack_set_thread_creator()...')
result = context.TryLink(jack_test_source_file, '.c')
context.Result(result)
return result
conf = Configure(fst, custom_tests = {
'CheckJackSetThreadCreator' : CheckJackSetThreadCreator,
})
if conf.CheckJackSetThreadCreator():
fst.Append(CCFLAGS="-DHAVE_JACK_SET_THREAD_CREATOR")
fst = conf.Finish ()
if fst['VST']: if fst['VST']:
fst.Replace(CC = ("winegcc"))
a = fst.Object ('fst', 'fst.c') a = fst.Object ('fst', 'fst.c')
b = fst.Object ('fstinfofile', 'fstinfofile.c') b = fst.Object ('fstinfofile', 'fstinfofile.c')
c = fst.Object ('vstwin', 'vstwin.c') c = fst.Object ('vstwin', 'vstwin.c')
d = fst.Object ('vsti', 'vsti.c') d = fst.Object ('vsti', 'vsti.c')
e = fst.Object ('thread', 'thread.c')
Default([a,b,c,d,e])
Default([a,b,c,d]) vestige_headers = glob.glob ('vestige/*.h')
env.Alias('tarball', env.Distribute (env['DISTTREE'], env.Alias('tarball', env.Distribute (env['DISTTREE'],
fst_src + ['SConscript', fst_src + vestige_headers +
['SConscript',
'fst.h', 'fst.h',
'jackvst.h' 'jackvst.h',
] )) ]
))

View File

@ -80,8 +80,10 @@ struct _FST
int height; int height;
int wantIdle; int wantIdle;
int destroy; int destroy;
int vst_version;
int want_program; int want_program;
int current_program;
float *want_params; float *want_params;
float *set_params; float *set_params;
@ -105,6 +107,7 @@ extern "C" {
#endif #endif
extern int fst_init (void* possible_hmodule); extern int fst_init (void* possible_hmodule);
extern void fst_exit ();
extern FSTHandle* fst_load (const char*); extern FSTHandle* fst_load (const char*);
extern int fst_unload (FSTHandle*); extern int fst_unload (FSTHandle*);
@ -133,6 +136,9 @@ extern int fst_load_state (FST * fst, char * filename);
*/ */
extern int fst_save_state (FST * fst, char * filename); extern int fst_save_state (FST * fst, char * filename);
extern int wine_pthread_create (pthread_t* thread_id, const pthread_attr_t* attr, void *(*function)(void*), void* arg);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -26,6 +26,7 @@
#ifndef _AEFFECTX_H #ifndef _AEFFECTX_H
#define _AEFFECTX_H #define _AEFFECTX_H
#include <stdint.h>
#define audioMasterAutomate 0 #define audioMasterAutomate 0
#define audioMasterVersion 1 #define audioMasterVersion 1
@ -128,9 +129,18 @@
#define kVstLangEnglish 1 #define kVstLangEnglish 1
#define kVstMidiType 1 #define kVstMidiType 1
#define kVstTransportPlaying (1 << 1) #define kVstTransportPlaying (1 << 1)
#define kVstParameterUsesFloatStep (1 << 2)
/* validity flags for a VstTimeINfo structure this info comes from the web */
#define kVstNanosValid (1 << 8)
#define kVstPpqPosValid (1 << 9)
#define kVstTempoValid (1 << 10) #define kVstTempoValid (1 << 10)
#define kVstBarsValid (1 << 11) #define kVstBarsValid (1 << 11)
#define kVstCyclePosValid (1 << 12)
#define kVstTimeSigValid (1 << 13)
#define kVstSmpteValid (1 << 14)
#define kVstClockValid (1 << 15)
#define kVstTransportChanged 1 #define kVstTransportChanged 1
typedef struct VstMidiEvent typedef struct VstMidiEvent
@ -182,27 +192,49 @@ typedef struct VstEvents
VstEvent * events[]; VstEvent * events[];
} VstEvents; } VstEvents;
/* constants from http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=3740&sid=183f74631fee71a493316735e2b9f28b */
enum Vestige2StringConstants
// Not finished, neither really used
typedef struct VstParameterProperties
{ {
float stepFloat; VestigeMaxNameLen = 64,
char label[64]; VestigeMaxLabelLen = 64,
int flags; VestigeMaxShortLabelLen = 8,
int minInteger; VestigeMaxCategLabelLen = 24,
int maxInteger; VestigeMaxFileNameLen = 100
int stepInteger; };
char shortLabel[8];
int category;
char categoryLabel[24];
char empty[128];
} VstParameterProperties;
/* this struct taken from http://asseca.com/vst-24-specs/efGetParameterProperties.html */
struct VstParameterProperties
{
float stepFloat; /* float step */
float smallStepFloat; /* small float step */
float largeStepFloat; /* large float step */
char label[VestigeMaxLabelLen]; /* parameter label */
int32_t flags; /* @see VstParameterFlags */
int32_t minInteger; /* integer minimum */
int32_t maxInteger; /* integer maximum */
int32_t stepInteger; /* integer step */
int32_t largeStepInteger; /* large integer step */
char shortLabel[VestigeMaxShortLabelLen]; /* short label, recommended: 6 + delimiter */
int16_t displayIndex; /* index where this parameter should be displayed (starting with 0) */
int16_t category; /* 0: no category, else group index + 1 */
int16_t numParametersInCategory; /* number of parameters in category */
int16_t reserved; /* zero */
char categoryLabel[VestigeMaxCategLabelLen]; /* category label, e.g. "Osc 1" */
char future[16]; /* reserved for future use */
};
/* this enum taken from http://asseca.com/vst-24-specs/efGetParameterProperties.html */
enum VstParameterFlags
{
kVstParameterIsSwitch = 1 << 0, /* parameter is a switch (on/off) */
kVstParameterUsesIntegerMinMax = 1 << 1, /* minInteger, maxInteger valid */
kVstParameterUsesFloatStep = 1 << 2, /* stepFloat, smallStepFloat, largeStepFloat valid */
kVstParameterUsesIntStep = 1 << 3, /* stepInteger, largeStepInteger valid */
kVstParameterSupportsDisplayIndex = 1 << 4, /* displayIndex valid */
kVstParameterSupportsDisplayCategory = 1 << 5, /* category, etc. valid */
kVstParameterCanRamp = 1 << 6 /* set if parameter value can ramp up/down */
};
typedef struct AEffect typedef struct AEffect
{ {
@ -253,30 +285,26 @@ typedef struct AEffect
typedef struct VstTimeInfo typedef struct VstTimeInfo
{ {
// 00 /* info from online documentation of VST provided by Steinberg */
double samplePos; double samplePos;
// 08
double sampleRate; double sampleRate;
// unconfirmed 10 18 double nanoSeconds;
char empty1[8 + 8]; double ppqPos;
// 20?
double tempo; double tempo;
// unconfirmed 28 30 38 double barStartPos;
char empty2[8 + 8 + 8]; double cycleStartPos;
// 40? double cycleEndPos;
int timeSigNumerator; double timeSigNumerator;
// 44? double timeSigDenominator;
int timeSigDenominator; long smpteOffset;
// unconfirmed 48 4c 50 long smpteFrameRate;
char empty3[4 + 4 + 4]; long samplesToNextClock;
// 54 long flags;
int flags;
} VstTimeInfo; } VstTimeInfo;
typedef long int (* audioMasterCallback)( AEffect * , long int , long int , typedef long int (* audioMasterCallback)( AEffect * , long int , long int ,
long int , void * , float ); long int , void * , float );
// we don't use it, may be noise // we don't use it, may be noise

View File

@ -1,4 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include <jack/jack.h>
#include <jack/thread.h>
#include <libgen.h> #include <libgen.h>
#include <windows.h> #include <windows.h>
#include <winnt.h> #include <winnt.h>
@ -24,11 +26,7 @@ static FST* fst_first = NULL;
const char magic[] = "FST Plugin State v002"; const char magic[] = "FST Plugin State v002";
DWORD gui_thread_id = 0; DWORD gui_thread_id = 0;
static int gui_quit = 0;
extern boolean g_quit;
#define DELAYED_WINDOW 1 #define DELAYED_WINDOW 1
@ -36,12 +34,11 @@ extern boolean g_quit;
static LRESULT WINAPI static LRESULT WINAPI
my_window_proc (HWND w, UINT msg, WPARAM wp, LPARAM lp) my_window_proc (HWND w, UINT msg, WPARAM wp, LPARAM lp)
{ {
FST* fst=NULL; #if 0
LRESULT result; if (msg != WM_TIMER) {
fst_error ("window callback handler, msg = 0x%x win=%p\n", msg, w);
// if (msg != WM_TIMER) { }
// fst_error ("window callback handler, msg = 0x%x win=%p\n", msg, w); #endif
// }
switch (msg) { switch (msg) {
case WM_KEYUP: case WM_KEYUP:
@ -49,47 +46,21 @@ my_window_proc (HWND w, UINT msg, WPARAM wp, LPARAM lp)
break; break;
case WM_CLOSE: case WM_CLOSE:
//printf("wtf.\n" ); /* we don't care about windows closing ... */
PostQuitMessage (0); return 0;
break;
case WM_DESTROY: case WM_DESTROY:
case WM_NCDESTROY: case WM_NCDESTROY:
/* we should never get these */ /* we don't care about windows being destroyed ... */
//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);
}
}
break;
#endif
#if 0
case WM_TIMER:
fst = GetPropA( w, "fst_ptr" );
if( !fst ) {
printf( "Timer without fst_ptr Prop :(\n" );
return 0; return 0;
} break;
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: default:
break; break;
} }
return DefWindowProcA (w, msg, wp, lp ); return DefWindowProcA (w, msg, wp, lp );
//return 0;
} }
static FST* static FST*
@ -100,6 +71,7 @@ fst_new ()
pthread_cond_init (&fst->window_status_change, NULL); pthread_cond_init (&fst->window_status_change, NULL);
pthread_cond_init (&fst->plugin_dispatcher_called, NULL); pthread_cond_init (&fst->plugin_dispatcher_called, NULL);
fst->want_program = -1; fst->want_program = -1;
fst->current_program = -1;
return fst; return fst;
} }
@ -114,7 +86,6 @@ DWORD WINAPI gui_event_loop (LPVOID param)
{ {
MSG msg; MSG msg;
FST* fst; FST* fst;
char c;
HMODULE hInst; HMODULE hInst;
HWND window; HWND window;
@ -141,7 +112,17 @@ DWORD WINAPI gui_event_loop (LPVOID param)
fst_error ("cannot set timer on dummy window"); fst_error ("cannot set timer on dummy window");
} }
while (GetMessageA (&msg, NULL, 0,0)) { while (!gui_quit) {
if (!GetMessageA (&msg, NULL, 0,0)) {
if (!gui_quit) {
fprintf (stderr, "QUIT message received by Windows GUI thread - ignored\n");
continue;
} else {
break;
}
}
TranslateMessage( &msg ); TranslateMessage( &msg );
DispatchMessageA (&msg); DispatchMessageA (&msg);
@ -151,10 +132,14 @@ DWORD WINAPI gui_event_loop (LPVOID param)
if (msg.message == WM_TIMER) { if (msg.message == WM_TIMER) {
pthread_mutex_lock (&plugin_mutex); pthread_mutex_lock (&plugin_mutex);
again: again:
for (fst = fst_first; fst; fst = fst->next) { for (fst = fst_first; fst; fst = fst->next) {
pthread_mutex_lock (&fst->lock);
if (fst->destroy) { if (fst->destroy) {
fprintf (stderr, "%s scheduled for destroy\n", fst->handle->name);
if (fst->window) { if (fst->window) {
fst->plugin->dispatcher( fst->plugin, effEditClose, 0, 0, NULL, 0.0 ); fst->plugin->dispatcher( fst->plugin, effEditClose, 0, 0, NULL, 0.0 );
CloseWindow (fst->window); CloseWindow (fst->window);
@ -163,53 +148,62 @@ again:
} }
fst_event_loop_remove_plugin (fst); fst_event_loop_remove_plugin (fst);
fst->been_activated = FALSE; fst->been_activated = FALSE;
pthread_mutex_lock (&fst->lock);
pthread_cond_signal (&fst->window_status_change); pthread_cond_signal (&fst->window_status_change);
pthread_mutex_unlock (&fst->lock); pthread_mutex_unlock (&fst->lock);
goto again; goto again;
} }
if (fst->window == NULL) { 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)) { if (fst_create_editor (fst)) {
fst_error ("cannot create editor for plugin %s", fst->handle->name); fst_error ("cannot create editor for plugin %s", fst->handle->name);
fst_event_loop_remove_plugin (fst); fst_event_loop_remove_plugin (fst);
pthread_cond_signal (&fst->window_status_change); pthread_cond_signal (&fst->window_status_change);
pthread_mutex_unlock (&fst->lock); pthread_mutex_unlock (&fst->lock);
goto again; goto again;
} } else {
/* condition/unlock: it was signalled & unlocked in fst_create_editor() */ /* condition/unlock: it was signalled & unlocked in fst_create_editor() */
} }
}
if (fst->want_program != -1 ) { if (fst->want_program != -1 ) {
if (fst->vst_version >= 2) {
fst->plugin->dispatcher (fst->plugin, 67 /* effBeginSetProgram */, 0, 0, NULL, 0);
}
fst->plugin->dispatcher (fst->plugin, effSetProgram, 0, fst->want_program, NULL, 0); fst->plugin->dispatcher (fst->plugin, effSetProgram, 0, fst->want_program, NULL, 0);
if (fst->vst_version >= 2) {
fst->plugin->dispatcher (fst->plugin, 68 /* effEndSetProgram */, 0, 0, NULL, 0);
}
/* did it work? */
fst->current_program = fst->plugin->dispatcher (fst->plugin, 3, /* effGetProgram */ 0, 0, NULL, 0);
fst->want_program = -1; fst->want_program = -1;
} }
if(fst->dispatcher_wantcall) { if(fst->dispatcher_wantcall) {
fst->dispatcher_retval = fst->plugin->dispatcher( fst->plugin,
pthread_mutex_lock (&fst->lock); fst->dispatcher_opcode,
fst->dispatcher_retval = fst->plugin->dispatcher( fst->plugin, fst->dispatcher_opcode,
fst->dispatcher_index, fst->dispatcher_index,
fst->dispatcher_val, fst->dispatcher_val,
fst->dispatcher_ptr, fst->dispatcher_ptr,
fst->dispatcher_opt ); fst->dispatcher_opt );
fst->dispatcher_wantcall = 0; fst->dispatcher_wantcall = 0;
pthread_cond_signal (&fst->plugin_dispatcher_called); 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); fst->plugin->dispatcher (fst->plugin, effEditIdle, 0, 0, NULL, 0);
if( fst->wantIdle ) { if( fst->wantIdle ) {
fst->plugin->dispatcher (fst->plugin, 53, 0, 0, NULL, 0); fst->plugin->dispatcher (fst->plugin, 53, 0, 0, NULL, 0);
} }
pthread_mutex_unlock (&fst->lock); pthread_mutex_unlock (&fst->lock);
} }
pthread_mutex_unlock (&plugin_mutex); pthread_mutex_unlock (&plugin_mutex);
} }
} }
fprintf (stderr, "VST GUI EVENT LOOP THREAD EXIT\n");
return 0; return 0;
} }
@ -225,6 +219,7 @@ fst_init (void* possible_hmodule)
fst_error ("can't get module handle"); fst_error ("can't get module handle");
return -1; return -1;
} }
wclass.cbSize = sizeof(WNDCLASSEX); wclass.cbSize = sizeof(WNDCLASSEX);
wclass.style = 0; wclass.style = 0;
wclass.lpfnWndProc = my_window_proc; wclass.lpfnWndProc = my_window_proc;
@ -238,19 +233,6 @@ fst_init (void* possible_hmodule)
wclass.lpszClassName = "FST"; wclass.lpszClassName = "FST";
wclass.hIconSm = 0; 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)){ if (!RegisterClassExA(&wclass)){
printf( "Class register failed :(\n" ); printf( "Class register failed :(\n" );
@ -263,9 +245,21 @@ fst_init (void* possible_hmodule)
fst_error ("could not create new thread proxy"); fst_error ("could not create new thread proxy");
return -1; return -1;
} }
#ifdef HAVE_JACK_SET_THREAD_CREATOR
jack_set_thread_creator (wine_pthread_create);
#endif
return 0; return 0;
} }
void
fst_exit ()
{
gui_quit = 1;
PostQuitMessage (0);
}
int int
fst_run_editor (FST* fst) fst_run_editor (FST* fst)
{ {
@ -319,7 +313,6 @@ int
fst_create_editor (FST* fst) fst_create_editor (FST* fst)
{ {
HMODULE hInst; HMODULE hInst;
char class[20];
HWND window; HWND window;
struct ERect* er; struct ERect* er;
@ -372,9 +365,7 @@ fst_create_editor (FST* fst)
//SetWindowPos (fst->window, 0, 0, 0, er->right-er->left+8, er->bottom-er->top+26, SWP_NOMOVE|SWP_NOZORDER); //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"); fst->xid = (int) GetPropA (window, "__wine_x11_whole_window");
printf( "And xid = %x\n", fst->xid );
fst->been_activated = TRUE; fst->been_activated = TRUE;
printf ("Signalling window ready\n");
pthread_cond_signal (&fst->window_status_change); pthread_cond_signal (&fst->window_status_change);
pthread_mutex_unlock (&fst->lock); pthread_mutex_unlock (&fst->lock);
@ -393,17 +384,16 @@ fst_move_window_into_view (FST* fst)
void void
fst_destroy_editor (FST* fst) fst_destroy_editor (FST* fst)
{ {
FST* p;
FST* prev;
pthread_mutex_lock (&fst->lock); pthread_mutex_lock (&fst->lock);
if (fst->window) { if (fst->window) {
fprintf (stderr, "mark %s for destroy\n", fst->handle->name);
fst->destroy = TRUE; fst->destroy = TRUE;
//if (!PostThreadMessageA (gui_thread_id, WM_USER, 0, 0)) { //if (!PostThreadMessageA (gui_thread_id, WM_USER, 0, 0)) {
//if (!PostThreadMessageA (gui_thread_id, WM_QUIT, 0, 0)) { //if (!PostThreadMessageA (gui_thread_id, WM_QUIT, 0, 0)) {
// fst_error ("could not post message to gui thread"); // fst_error ("could not post message to gui thread");
//} //}
pthread_cond_wait (&fst->window_status_change, &fst->lock); pthread_cond_wait (&fst->window_status_change, &fst->lock);
fprintf (stderr, "%s editor destroyed\n", fst->handle->name);
} }
pthread_mutex_unlock (&fst->lock); pthread_mutex_unlock (&fst->lock);
@ -481,7 +471,7 @@ fst_load_vst_library(const char * path)
FSTHandle* FSTHandle*
fst_load (const char *path) fst_load (const char *path)
{ {
char* buf, *buf2; char* buf;
FSTHandle* fhandle; FSTHandle* fhandle;
char* period; char* period;
@ -585,6 +575,8 @@ fst_instantiate (FSTHandle* fhandle, audioMasterCallback amc, void* userptr)
fst->plugin->dispatcher (fst->plugin, effOpen, 0, 0, 0, 0); fst->plugin->dispatcher (fst->plugin, effOpen, 0, 0, 0, 0);
//fst->plugin->dispatcher (fst->plugin, effMainsChanged, 0, 0, NULL, 0); //fst->plugin->dispatcher (fst->plugin, effMainsChanged, 0, 0, NULL, 0);
fst->vst_version = fst->plugin->dispatcher (fst->plugin, effGetVstVersion, 0, 0, 0, 0);
fst->handle->plugincnt++; fst->handle->plugincnt++;
fst->wantIdle = 0; fst->wantIdle = 0;
@ -742,7 +734,6 @@ int fst_save_state (FST * fst, char * filename)
char effectName[64]; char effectName[64];
char vendorString[64]; char vendorString[64];
int success; int success;
unsigned length;
// write header // write header
fprintf( f, "<plugin_state>\n" ); fprintf( f, "<plugin_state>\n" );