made VST support layer work on native win32

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1546 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2008-09-04 16:21:38 +00:00
parent 30db9fc779
commit a7e2ca44bb
9 changed files with 165 additions and 52 deletions

View File

@@ -258,7 +258,7 @@ ENDIF(WANT_SF2)
# check for WINE
if(WANT_VST)
IF(WANT_VST)
INCLUDE(CheckLibraryExists)
INCLUDE(CheckIncludeFileCXX)
SET(CMAKE_REQUIRED_FLAGS_ORIG ${CMAKE_REQUIRED_FLAGS})
@@ -276,11 +276,15 @@ if(WANT_VST)
SET(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_ORIG})
IF(HAVE_LIBWINE AND HAVE_WINDOWS_H)
SET(LMMS_HAVE_VST TRUE)
SET(STATUS_WINE "OK")
SET(STATUS_VST "OK")
ELSE(HAVE_LIBWINE AND HAVE_WINDOWS_H)
SET(STATUS_WINE "not found, please install (lib)wine-dev (or similiar) - 64 bit systems additionally need gcc-multilib and g++-multilib")
SET(STATUS_VST "not found, please install (lib)wine-dev (or similiar) - 64 bit systems additionally need gcc-multilib and g++-multilib")
ENDIF(HAVE_LIBWINE AND HAVE_WINDOWS_H)
ENDIF(WANT_VST)
IF(LMMS_BUILD_WIN32)
SET(LMMS_HAVE_VST TRUE)
SET(STATUS_VST "OK")
ENDIF(LMMS_BUILD_WIN32)
# check for libsamplerate
@@ -515,8 +519,8 @@ MESSAGE(
"----------------\n"
"* SoundFont2 player : ${STATUS_FLUIDSYNTH}\n"
"* Stk Mallets : ${STATUS_STK}\n"
"* VST-instrument hoster : ${STATUS_WINE}\n"
"* VST-effect hoster : ${STATUS_WINE}\n"
"* VST-instrument hoster : ${STATUS_VST}\n"
"* VST-effect hoster : ${STATUS_VST}\n"
"* SpectrumAnalyzer : ${STATUS_FFTW3F}\n"
"* CAPS LADSPA plugins : ${STATUS_CAPS}\n"
"* TAP LADSPA plugins : ${STATUS_TAP}\n"

View File

@@ -1,3 +1,15 @@
2008-09-04 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* plugins/vst_base/vst_plugin.h:
* plugins/vst_base/remote_vst_plugin.cpp:
* plugins/vst_base/communication.h:
* plugins/vst_base/vst_plugin.cpp:
* plugins/vst_base/CMakeLists.txt:
* include/text_float.h:
* include/remote_plugin.h:
* CMakeLists.txt:
made VST support layer work on native win32
2008-09-03 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* plugins/vst_base/communication.h:

View File

@@ -40,6 +40,8 @@
#include <process.h>
#endif
#include <Qt/qglobal.h>
#if QT_VERSION >= 0x040400
#include <QtCore/QSharedMemory>
#include <QtCore/QSystemSemaphore>

View File

@@ -29,8 +29,10 @@
#include <QtGui/QWidget>
#include <QtGui/QPixmap>
#include "export.h"
class textFloat : public QWidget
class EXPORT textFloat : public QWidget
{
public:
textFloat( void );

View File

@@ -4,6 +4,18 @@ INCLUDE(BuildPlugin)
BUILD_PLUGIN(vstbase vst_base.cpp vst_plugin.cpp vst_plugin.h communication.h MOCFILES vst_plugin.h)
IF(LMMS_BUILD_WIN32)
ADD_DEFINITIONS(-DPTW32_STATIC_LIB)
LINK_LIBRARIES(-lQtCore4 -lpthread -lgdi32 -lwsock32)
ADD_EXECUTABLE(remote_vst_plugin ${CMAKE_CURRENT_SOURCE_DIR}/remote_vst_plugin.cpp)
ENDIF(LMMS_BUILD_WIN32)
IF(LMMS_BUILD_LINUX)
IF(LMMS_HOST_X86_64)
SET(EXTRA_FLAGS -m32 -Wb,--as-cmd='as --32',--ld-cmd='ld -melf_i386' -L/usr/lib32)
ENDIF(LMMS_HOST_X86_64)
@@ -19,4 +31,7 @@ SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES remote_vst_plugi
INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/remote_vst_plugin ${CMAKE_CURRENT_BINARY_DIR}/remote_vst_plugin.exe.so DESTINATION ${PLUGIN_DIR})
ENDIF(LMMS_BUILD_LINUX)
ENDIF(LMMS_HAVE_VST)

View File

@@ -55,6 +55,7 @@ enum VstRemoteMessageIDs
{
// vstPlugin -> remoteVstPlugin
IdVstLoadPlugin = IdUserBase,
IdVstPluginWindowInformation,
IdVstClosePlugin,
IdVstSetTempo,
IdVstSetLanguage,

View File

@@ -38,13 +38,22 @@
#include <pthread.h>
#endif
#ifdef LMMS_BUILD_LINUX
#ifdef LMMS_HAVE_SCHED_H
#include <sched.h>
#endif
#include <wine/exception.h>
#endif
#include <windows.h>
#include <wine/exception.h>
#ifdef LMMS_BUILD_WIN32
#include <libgen.h>
#endif
#include <list>
@@ -76,6 +85,7 @@ struct ERect
#include "communication.h"
#if 0
#ifdef LMMS_HAVE_TLS
static __thread int ejmpbuf_valid = false;
static __thread jmp_buf ejmpbuf;
@@ -83,6 +93,7 @@ static __thread jmp_buf ejmpbuf;
static pthread_key_t ejmpbuf_valid_key;
static pthread_key_t ejmpbuf_key;
#endif
#endif
static VstHostLanguages hlang = LanguageEnglish;
@@ -105,15 +116,6 @@ public:
void init( const std::string & _plugin_file );
void showEditor( void )
{
if( m_window != NULL )
{
PostThreadMessageA( m_guiThreadID, WM_USER, ShowEditor,
0 );
}
}
virtual bool process( const sampleFrame * _in, sampleFrame * _out );
@@ -190,9 +192,9 @@ public:
private:
enum guiThreadMessages
enum GuiThreadMessages
{
None, ShowEditor, ClosePlugin
None, ClosePlugin
} ;
// callback used by plugin for being able to communicate with it's host
@@ -252,6 +254,8 @@ remoteVstPlugin::remoteVstPlugin( key_t _shm_in, key_t _shm_out ) :
m_bpm( 0 ),
m_currentSamplePos( 0 )
{
pthread_mutex_init( &m_lock, NULL );
pthread_cond_init( &m_windowStatusChange, NULL );
}
@@ -266,9 +270,12 @@ remoteVstPlugin::~remoteVstPlugin()
{
//lvsMessage( "could not post message to gui thread" );
}
pthread_mutex_lock( &m_lock );
pthread_cond_wait( &m_windowStatusChange, &m_lock );
m_plugin->dispatcher( m_plugin, effEditClose, 0, 0, NULL, 0.0 );
#ifdef LMMS_BUILD_LINUX
CloseWindow( m_window );
#endif
m_window = NULL;
}
@@ -280,6 +287,9 @@ remoteVstPlugin::~remoteVstPlugin()
delete[] m_inputs;
delete[] m_outputs;
pthread_mutex_destroy( &m_lock );
pthread_cond_destroy( &m_windowStatusChange );
}
@@ -293,9 +303,15 @@ bool remoteVstPlugin::processMessage( const message & _m )
init( _m.getString() );
break;
case IdShowUI:
showEditor();
#ifdef LMMS_BUILD_WIN32
case IdVstPluginWindowInformation:
{
HWND top = FindWindowEx( NULL, NULL, NULL,
_m.getString().c_str() );
m_window = FindWindowEx( top, NULL, NULL, NULL );
break;
}
#endif
case IdVstSetTempo:
setBPM( _m.getInt() );
@@ -350,18 +366,16 @@ void remoteVstPlugin::init( const std::string & _plugin_file )
fprintf( stderr, "could not create GUI-thread\n" );
return;
}
pthread_cond_wait( &m_windowStatusChange, &m_lock);
pthread_mutex_lock( &m_lock );
pthread_cond_wait( &m_windowStatusChange, &m_lock );
// now post some information about our plugin
sendMessage( message( IdVstPluginWindowID ).addInt( m_windowID ) );
if( m_windowID != 0 )
{
sendMessage( message( IdVstPluginEditorGeometry ).
sendMessage( message( IdVstPluginEditorGeometry ).
addInt( m_windowWidth ).
addInt( m_windowHeight ) );
}
sendMessage( message( IdVstPluginName ).addString( pluginName() ) );
sendMessage( message( IdVstPluginVersion ).addInt( pluginVersion() ) );
@@ -480,9 +494,6 @@ bool remoteVstPlugin::process( const sampleFrame * _in, sampleFrame * _out )
m_currentSamplePos += bufferSize();
// give plugin some idle-time for GUI-update and so on...
m_plugin->dispatcher( m_plugin, effEditIdle, 0, 0, NULL, 0 );
}
@@ -984,6 +995,7 @@ DWORD WINAPI remoteVstPlugin::guiEventLoop( LPVOID _param )
remoteVstPlugin * _this = static_cast<remoteVstPlugin *>( _param );
_this->m_guiThreadID = GetCurrentThreadId();
#if 0
// "guard point" to trap errors that occur during plugin loading
#ifdef LMMS_HAVE_TLS
if( sigsetjmp( ejmpbuf, 1 ) )
@@ -1005,12 +1017,17 @@ DWORD WINAPI remoteVstPlugin::guiEventLoop( LPVOID _param )
pthread_key_create( &ejmpbuf_valid_key, NULL );
pthread_setspecific( ejmpbuf_valid_key, ejmpbuf_valid );
#ifdef LMMS_BUILD_WIN32
if( setjmp( *ejmpbuf ) )
#else
if( sigsetjmp( *ejmpbuf, 1 ) )
#endif
{
exit( 1 );
}
*ejmpbuf_valid = true;
#endif
#endif
// Note: m_lock is held while this function is called
@@ -1029,21 +1046,27 @@ DWORD WINAPI remoteVstPlugin::guiEventLoop( LPVOID _param )
return( 1 );
}
#ifdef LMMS_BUILD_LINUX
if( ( _this->m_window = CreateWindowExA(
0, "LVSL", _this->m_shortName.c_str(),
( WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME &
( WS_OVERLAPPEDWINDOW | WS_THICKFRAME &
~WS_MAXIMIZEBOX ),
0, 0, 1, 1, NULL, NULL, hInst, NULL ) ) == NULL )
0, 0, 10, 10,
NULL, NULL, hInst, NULL ) ) == NULL )
{
fprintf( stderr, "cannot create editor window\n" );
pthread_cond_signal( &_this->m_windowStatusChange );
return( 1 );
}
ShowWindow( _this->m_window, SW_SHOWMINIMIZED );
ShowWindow( _this->m_window, SW_HIDE );
ShowWindow( _this->m_window, SW_SHOWNORMAL );
_this->m_windowID = (Sint32) GetPropA( _this->m_window,
"__wine_x11_whole_window" );
#else
_this->m_windowID = 1; // arbitrary value on win32 to signal
// vstPlugin-class that we have an editor
#endif
_this->m_plugin->dispatcher( _this->m_plugin, effEditOpen, 0, 0,
@@ -1055,23 +1078,28 @@ DWORD WINAPI remoteVstPlugin::guiEventLoop( LPVOID _param )
_this->m_windowWidth = er->right - er->left;
_this->m_windowHeight = er->bottom - er->top;
SetWindowPos( _this->m_window, 0, 0, 0, _this->m_windowWidth + 8,
_this->m_windowHeight + 26, 0
_this->m_windowHeight + 26, SWP_SHOWWINDOW );
UpdateWindow( _this->m_window );
#if 0
SWP_NOACTIVATE /*| SWP_NOREDRAW*/ | SWP_NOMOVE |
SWP_NOOWNERZORDER | SWP_NOZORDER
#endif
);
#ifdef LMMS_HAVE_TLS
ejmpbuf_valid = false;
#else
*ejmpbuf_valid = false;
#endif
#endif
pthread_cond_signal( &_this->m_windowStatusChange );
HWND timer_window = CreateWindowEx( 0, "LVSL", "dummy",
0, 0, 0, 0, 0, NULL, NULL, hInst, NULL );
// install GUI update timer
SetTimer( timer_window, 1000, 50, NULL );
MSG msg;
bool quit = false;
@@ -1080,16 +1108,17 @@ DWORD WINAPI remoteVstPlugin::guiEventLoop( LPVOID _param )
TranslateMessage( &msg );
DispatchMessageA( &msg );
if( msg.message == WM_USER )
if( msg.message == WM_TIMER )
{
// give plugin some idle-time for GUI-update
_this->m_plugin->dispatcher( _this->m_plugin,
effEditIdle, 0, 0,
NULL, 0 );
}
else if( msg.message == WM_USER )
{
switch( msg.wParam )
{
case ShowEditor:
ShowWindow( _this->m_window,
SW_SHOWNORMAL );
UpdateWindow( _this->m_window );
break;
case ClosePlugin:
quit = true;
break;
@@ -1108,7 +1137,7 @@ DWORD WINAPI remoteVstPlugin::guiEventLoop( LPVOID _param )
int main( int _argc, char * * _argv )
int main( int _argc, char * * _argv )
{
if( _argc < 3 )
{
@@ -1147,6 +1176,7 @@ int main( int _argc, char * * _argv )
return( -1 );
}
#ifdef LMMS_BUILD_LINUX
#ifdef LMMS_HAVE_SCHED_H
// try to set realtime-priority
struct sched_param sparam;
@@ -1157,6 +1187,7 @@ int main( int _argc, char * * _argv )
fprintf( stderr, "could not set realtime priority for "
"remoteVstPlugin\n" );
}
#endif
#endif
__plugin = new remoteVstPlugin( atoi( _argv[1] ), atoi( _argv[2] ) );

View File

@@ -30,11 +30,20 @@
#include <QtCore/QLocale>
#include <QtGui/QMdiArea>
#include <QtGui/QMdiSubWindow>
#ifdef LMMS_BUILD_LINUX
#include <QtGui/QX11EmbedContainer>
#include <QtGui/QX11Info>
#else
#include <QtGui/QLayout>
#endif
#include <QtXml/QDomDocument>
#ifdef LMMS_BUILD_WIN32
#include <windows.h>
#endif
#include "config_mgr.h"
#include "engine.h"
#include "main_window.h"
@@ -42,7 +51,6 @@
vstPlugin::vstPlugin( const QString & _plugin ) :
QObject(),
journallingObject(),
@@ -58,6 +66,26 @@ vstPlugin::vstPlugin( const QString & _plugin ) :
setSplittedChannels( true );
lock();
#ifdef LMMS_BUILD_WIN32
QWidget * helper = new QWidget;
QWidget * target = new QWidget( helper );
QHBoxLayout * l = new QHBoxLayout;
l->setMargin( 0 );
l->addWidget( target );
helper->setLayout( l );
static int k = 0;
const QString t = QString( "vst%1%2" ).arg( GetCurrentProcessId()<<10 ).
arg( ++k );
helper->setWindowTitle( t );
// we've to call that for making sure, Qt created the windows
(void) helper->winId();
(void) target->winId();
sendMessage( message( IdVstPluginWindowInformation ).
addString( t.toStdString() ) );
#endif
VstHostLanguages hlang = LanguageEnglish;
switch( QLocale::system().language() )
@@ -83,6 +111,21 @@ vstPlugin::vstPlugin( const QString & _plugin ) :
waitForInitDone();
unlock();
#ifdef LMMS_BUILD_WIN32
if( m_pluginWindowID )
{
target->setFixedSize( m_pluginGeometry );
engine::getMainWindow()->workspace()->addSubWindow( helper )
->setAttribute( Qt::WA_DeleteOnClose, FALSE );
helper->setWindowTitle( name() );
m_pluginWidget = helper;
}
else
{
delete helper;
}
#endif
}
@@ -112,7 +155,7 @@ QWidget * vstPlugin::showEditor( QWidget * _parent )
}
return( m_pluginWidget );
}
#ifdef LMMS_BUILD_LINUX
if( m_pluginWindowID == 0 )
{
return( NULL );
@@ -128,7 +171,6 @@ QWidget * vstPlugin::showEditor( QWidget * _parent )
->setAttribute( Qt::WA_DeleteOnClose, FALSE );
}
#ifdef LMMS_BUILD_LINUX
QX11EmbedContainer * xe = new QX11EmbedContainer( m_pluginWidget );
xe->embedClient( m_pluginWindowID );
xe->setFixedSize( m_pluginGeometry );
@@ -148,6 +190,9 @@ QWidget * vstPlugin::showEditor( QWidget * _parent )
void vstPlugin::hideEditor( void )
{
if( m_pluginWidget )
m_pluginWidget->hide();
return;
if( m_pluginWidget != NULL && m_pluginWidget->parentWidget() )
{
m_pluginWidget->parentWidget()->hide();
@@ -275,7 +320,7 @@ bool vstPlugin::processMessage( const message & _m )
const int w = _m.getInt( 0 );
const int h = _m.getInt( 1 );
m_pluginGeometry = QSize( w, h );
if( m_pluginWidget != NULL )
/* if( m_pluginWidget != NULL )
{
m_pluginWidget->setFixedSize(
m_pluginGeometry );
@@ -285,7 +330,7 @@ bool vstPlugin::processMessage( const message & _m )
)->setFixedSize(
m_pluginGeometry );
}
}
}*/
break;
}

View File

@@ -37,7 +37,8 @@
class vstPlugin : public QObject, public journallingObject, public remotePlugin
class PLUGIN_EXPORT vstPlugin : public QObject, public journallingObject,
public remotePlugin
{
Q_OBJECT
public: