Support ZynAddSubFx with MSVC (#6561)

This commit is contained in:
Dominic Clark
2023-01-02 23:42:46 +00:00
committed by GitHub
parent 79def0c3b5
commit d95c89760a
10 changed files with 120 additions and 135 deletions

View File

@@ -1,5 +1,12 @@
if(NOT FLTK_FOUND)
return()
endif()
INCLUDE(BuildPlugin)
find_package(Threads REQUIRED)
find_package(ZLIB REQUIRED)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# definitions for ZynAddSubFX
@@ -11,40 +18,20 @@ ELSE()
ADD_DEFINITIONS(-DOS_WINDOWS)
ENDIF()
# do not conflict with LMMS' Controller class
ADD_DEFINITIONS(-DController=ZynController)
# use asm optimizations when on x86 or x86_64
IF(LMMS_HOST_X86 OR LMMS_HOST_X86_64)
if(NOT MSVC AND (LMMS_HOST_X86 OR LMMS_HOST_X86_64))
ADD_DEFINITIONS(-DASM_F2I_YES)
ENDIF(LMMS_HOST_X86 OR LMMS_HOST_X86_64)
endif()
# build ZynAddSubFX with full optimizations
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wno-write-strings -Wno-deprecated-declarations -fpermissive")
if(NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wno-write-strings -Wno-deprecated-declarations -fpermissive")
endif()
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "6.0.0")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-misleading-indentation")
ENDIF()
IF(LMMS_BUILD_WIN32)
# link system-libraries
ADD_DEFINITIONS(-DPTW32_STATIC_LIB)
# fix X11 headers errors caused by bug with mingw + c++11 (enable -std=gnu++0x)
SET(CMAKE_CXX_EXTENSIONS ON)
ENDIF(LMMS_BUILD_WIN32)
SET(FLTK_SKIP_OPENGL TRUE)
SET(FLTK_SKIP_FORMS TRUE)
SET(FLTK_SKIP_IMAGES TRUE)
SET(FLTK_SKIP_MATH TRUE)
IF(MINGW_PREFIX)
SET(FLTK_SKIP_FLUID TRUE)
ENDIF()
IF(NOT FLTK_FOUND)
RETURN()
ENDIF()
IF(MINGW_PREFIX)
SET(FLTK_FLUID_EXECUTABLE "${MINGW_PREFIX}/bin/fluid")
ENDIF()
@@ -57,13 +44,15 @@ IF(NOT EXISTS ${FLTK_FLUID_EXECUTABLE})
ENDIF()
ENDIF()
INCLUDE_DIRECTORIES("${FLTK_INCLUDE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}"
${FFTW3F_INCLUDE_DIRS}
"${CMAKE_CURRENT_BINARY_DIR}"
"${CMAKE_BINARY_DIR}")
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/zynaddsubfx/src/UI)
include_directories(
"${FLTK_INCLUDE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}"
${FFTW3F_INCLUDE_DIRS}
"${CMAKE_CURRENT_BINARY_DIR}"
"${CMAKE_BINARY_DIR}"
"${CMAKE_SOURCE_DIR}/src/3rdparty/mingw-std-threads"
"${CMAKE_CURRENT_SOURCE_DIR}/zynaddsubfx/src/UI"
)
ADD_DEFINITIONS(-DPLUGINVERSION) # removes exit confirmation dialogs etc. in MasterUI.fl
add_subdirectory(zynaddsubfx/src/Nio)
@@ -116,24 +105,23 @@ SET(zynaddsubfx_core_SRCS
zynaddsubfx/src/Synth/PADnote.cpp
zynaddsubfx/src/Synth/Resonance.cpp
zynaddsubfx/src/Synth/SUBnote.cpp
)
)
add_library(ZynAddSubFxCoreObjs OBJECT LocalZynAddSubFx.cpp ${zynaddsubfx_core_SRCS})
add_library(ZynAddSubFxCore INTERFACE)
target_sources(ZynAddSubFxCore INTERFACE
$<TARGET_OBJECTS:ZynAddSubFxCoreObjs>
$<TARGET_OBJECTS:zynaddsubfx_nio>
)
IF(LMMS_BUILD_LINUX)
ADD_LIBRARY(ZynAddSubFxCore MODULE LocalZynAddSubFx.cpp ${zynaddsubfx_core_SRCS})
ELSE()
ADD_LIBRARY(ZynAddSubFxCore SHARED LocalZynAddSubFx.cpp ${zynaddsubfx_core_SRCS})
ENDIF()
TARGET_LINK_LIBRARIES(ZynAddSubFxCore zynaddsubfx_nio ${FFTW3F_LIBRARIES} ${QT_LIBRARIES} -lz -lpthread)
TARGET_LINK_LIBRARIES(ZynAddSubFxCore Qt5::Widgets Qt5::Xml)
IF(LMMS_BUILD_WIN32)
TARGET_LINK_LIBRARIES(ZynAddSubFxCore -lws2_32)
INSTALL(TARGETS ZynAddSubFxCore RUNTIME DESTINATION "${PLUGIN_DIR}")
ELSE(LMMS_BUILD_WIN32)
INSTALL(TARGETS ZynAddSubFxCore LIBRARY DESTINATION "${PLUGIN_DIR}")
ENDIF(LMMS_BUILD_WIN32)
target_link_libraries(ZynAddSubFxCore INTERFACE
${FFTW3F_LIBRARIES}
${QT_LIBRARIES}
Qt5::Widgets
Qt5::Xml
Threads::Threads
ZLIB::ZLIB
)
LINK_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}/..")
IF(LMMS_BUILD_LINUX)
@@ -144,10 +132,11 @@ ELSE()
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${PLUGIN_DIR}")
ENDIF()
BUILD_PLUGIN(zynaddsubfx ZynAddSubFx.cpp ZynAddSubFx.h MOCFILES ZynAddSubFx.h EMBEDDED_RESOURCES artwork.png logo.png)
TARGET_LINK_LIBRARIES(zynaddsubfx -lZynAddSubFxCore)
ADD_DEPENDENCIES(zynaddsubfx ZynAddSubFxCore)
target_link_libraries(zynaddsubfx ZynAddSubFxCore)
IF(WIN32)
if(MSVC)
set(WINRC "${CMAKE_CURRENT_BINARY_DIR}/zynaddsubfx.rc")
elseif(WIN32)
SET(WINRC "${CMAKE_CURRENT_BINARY_DIR}/zynaddsubfxrc.obj")
ADD_CUSTOM_COMMAND(OUTPUT "${WINRC}"
COMMAND "${CMAKE_RC_COMPILER}"
@@ -155,14 +144,19 @@ IF(WIN32)
"-o\"${CMAKE_CURRENT_BINARY_DIR}/zynaddsubfxrc.obj\""
"-i\"${CMAKE_CURRENT_BINARY_DIR}/zynaddsubfx.rc\""
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/zynaddsubfx.rc")
ENDIF(WIN32)
endif()
# Use libraries in non-standard directories (e.g., another version of Qt)
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
ADD_SUBDIRECTORY("${LMMS_SOURCE_DIR}/src/common" common)
ADD_EXECUTABLE(RemoteZynAddSubFx RemoteZynAddSubFx.cpp ${LMMS_COMMON_SRCS} "${WINRC}")
add_executable(RemoteZynAddSubFx
RemoteZynAddSubFx.cpp
${LMMS_COMMON_SRCS}
"${WINRC}"
$<TARGET_OBJECTS:zynaddsubfx_gui>
)
INSTALL(TARGETS RemoteZynAddSubFx RUNTIME DESTINATION "${PLUGIN_DIR}")
# Needed to deploy dependencies of RemoteZynAddSubFx
SET_PROPERTY(GLOBAL APPEND PROPERTY PLUGINS_BUILT "RemoteZynAddSubFx")
@@ -182,8 +176,7 @@ IF(FLTK_CONFIG AND NOT (LMMS_BUILD_APPLE OR LMMS_BUILD_WIN32))
STRING(REPLACE " " ";" FLTK_FILTERED_LDFLAGS ${FLTK_FILTERED_LDFLAGS})
LIST(REMOVE_ITEM FLTK_FILTERED_LDFLAGS -lX11)
ENDIF()
TARGET_LINK_LIBRARIES(RemoteZynAddSubFx zynaddsubfx_gui -lZynAddSubFxCore ${FLTK_FILTERED_LDFLAGS} -lpthread )
ADD_DEPENDENCIES(RemoteZynAddSubFx ZynAddSubFxCore)
target_link_libraries(RemoteZynAddSubFx ZynAddSubFxCore ${FLTK_FILTERED_LDFLAGS})
if(LMMS_HAVE_LIBRT)
target_link_libraries(RemoteZynAddSubFx rt)
@@ -199,13 +192,6 @@ ENDIF(LMMS_BUILD_WIN32)
IF(LMMS_BUILD_WIN32)
add_custom_command(
TARGET ZynAddSubFxCore
POST_BUILD
COMMAND "${STRIP_COMMAND}" "$<TARGET_FILE:ZynAddSubFxCore>"
VERBATIM
COMMAND_EXPAND_LISTS
)
add_custom_command(
TARGET RemoteZynAddSubFx
POST_BUILD

View File

@@ -22,19 +22,25 @@
*
*/
#include <lmmsconfig.h>
#include "LocalZynAddSubFx.h"
#include "zynaddsubfx/src/Misc/Util.h"
#include <unistd.h>
#include <ctime>
#include "LocalZynAddSubFx.h"
#include "lmmsconfig.h"
#ifdef LMMS_BUILD_WIN32
# include <wchar.h>
# include "IoHelper.h"
#else
# include <unistd.h>
#endif
#include "MidiEvent.h"
#include "zynaddsubfx/src/Nio/NulEngine.h"
#include "zynaddsubfx/src/Misc/Master.h"
#include "zynaddsubfx/src/Misc/Part.h"
#include "zynaddsubfx/src/Misc/Util.h"
// Global variable in zynaddsubfx/src/globals.h
SYNTH_T* synth = nullptr;
@@ -53,14 +59,6 @@ LocalZynAddSubFx::LocalZynAddSubFx() :
{
if( s_instanceCount == 0 )
{
#ifdef LMMS_BUILD_WIN32
#ifndef __WINPTHREADS_VERSION
// (non-portable) initialization of statically linked pthread library
pthread_win32_process_attach_np();
pthread_win32_thread_attach_np();
#endif
#endif // LMMS_BUILD_WIN32
initConfig();
synth = new SYNTH_T;
@@ -143,14 +141,20 @@ void LocalZynAddSubFx::loadXML( const std::string & _filename )
{
char * f = strdup( _filename.c_str() );
pthread_mutex_lock( &m_master->mutex );
m_master->defaults();
m_master->loadXML( f );
pthread_mutex_unlock( &m_master->mutex );
{
const auto lock = std::lock_guard{m_master->mutex};
m_master->defaults();
m_master->loadXML( f );
}
m_master->applyparameters();
#ifdef LMMS_BUILD_WIN32
_wunlink(toWString(_filename).c_str());
#else
unlink( f );
#endif
free( f );
}
@@ -161,10 +165,11 @@ void LocalZynAddSubFx::loadPreset( const std::string & _filename, int _part )
{
char * f = strdup( _filename.c_str() );
pthread_mutex_lock( &m_master->mutex );
m_master->part[_part]->defaultsinstrument();
m_master->part[_part]->loadXMLinstrument( f );
pthread_mutex_unlock( &m_master->mutex );
{
const auto lock = std::lock_guard{m_master->mutex};
m_master->part[_part]->defaultsinstrument();
m_master->part[_part]->loadXMLinstrument( f );
}
m_master->applyparameters();
@@ -262,8 +267,13 @@ void LocalZynAddSubFx::processMidiEvent( const MidiEvent& event )
void LocalZynAddSubFx::processAudio( sampleFrame * _out )
{
#ifdef _MSC_VER
const auto outputl = static_cast<float*>(_alloca(synth->buffersize * sizeof(float)));
const auto outputr = static_cast<float*>(_alloca(synth->buffersize * sizeof(float)));
#else
float outputl[synth->buffersize];
float outputr[synth->buffersize];
#endif
m_master->GetAudioOutSamples( synth->buffersize, synth->samplerate, outputl, outputr );

View File

@@ -22,17 +22,19 @@
*
*/
#include "RemoteZynAddSubFx.h"
#include <lmmsconfig.h>
#ifdef LMMS_BUILD_WIN32
#include <winsock2.h>
#endif
#include <queue>
#include "ThreadShims.h"
#undef CursorShape // is, by mistake, not undefed in FL
#include "RemotePluginClient.h"
#include "RemoteZynAddSubFx.h"
#include "LocalZynAddSubFx.h"
#include "zynaddsubfx/src/Nio/Nio.h"
@@ -60,12 +62,12 @@ public:
sendMessage( IdInitDone );
waitForMessage( IdInitDone );
pthread_mutex_init( &m_guiMutex, nullptr );
pthread_create( &m_messageThreadHandle, nullptr, messageLoop, this );
m_messageThread = std::thread{&RemoteZynAddSubFx::messageLoop, this};
}
~RemoteZynAddSubFx() override
{
m_messageThread.join();
Nio::stop();
}
@@ -84,9 +86,8 @@ public:
message m;
while( ( m = receiveMessage() ).id != IdQuit )
{
pthread_mutex_lock( &m_master->mutex );
const auto lock = std::lock_guard{m_master->mutex};
processMessage( m );
pthread_mutex_unlock( &m_master->mutex );
}
m_guiExit = true;
}
@@ -102,9 +103,10 @@ public:
case IdHideUI:
case IdLoadSettingsFromFile:
case IdLoadPresetFile:
pthread_mutex_lock( &m_guiMutex );
m_guiMessages.push( _m );
pthread_mutex_unlock( &m_guiMutex );
{
const auto lock = std::lock_guard{m_guiMutex};
m_guiMessages.push( _m );
}
break;
case IdSaveSettingsToFile:
@@ -144,22 +146,13 @@ public:
LocalZynAddSubFx::processAudio( _out );
}
static void * messageLoop( void * _arg )
{
auto _this = static_cast<RemoteZynAddSubFx*>(_arg);
_this->messageLoop();
return nullptr;
}
void guiLoop();
private:
const int m_guiSleepTime;
pthread_t m_messageThreadHandle;
pthread_mutex_t m_guiMutex;
std::thread m_messageThread;
std::mutex m_guiMutex;
std::queue<RemotePluginClient::message> m_guiMessages;
bool m_guiExit;
@@ -189,12 +182,11 @@ void RemoteZynAddSubFx::guiLoop()
}
if( exitProgram == 1 )
{
pthread_mutex_lock( &m_master->mutex );
const auto lock = std::lock_guard{m_master->mutex};
sendMessage( IdHideUI );
exitProgram = 0;
pthread_mutex_unlock( &m_master->mutex );
}
pthread_mutex_lock( &m_guiMutex );
const auto lock = std::lock_guard{m_guiMutex};
while( m_guiMessages.size() )
{
RemotePluginClient::message m = m_guiMessages.front();
@@ -219,9 +211,8 @@ void RemoteZynAddSubFx::guiLoop()
{
ui->refresh_master_ui();
}
pthread_mutex_lock( &m_master->mutex );
const auto lock = std::lock_guard{m_master->mutex};
sendMessage( IdLoadSettingsFromFile );
pthread_mutex_unlock( &m_master->mutex );
break;
}
@@ -235,9 +226,8 @@ void RemoteZynAddSubFx::guiLoop()
ui->updatepanel();
ui->refresh_master_ui();
}
pthread_mutex_lock( &m_master->mutex );
const auto lock = std::lock_guard{m_master->mutex};
sendMessage( IdLoadPresetFile );
pthread_mutex_unlock( &m_master->mutex );
break;
}
@@ -245,7 +235,6 @@ void RemoteZynAddSubFx::guiLoop()
break;
}
}
pthread_mutex_unlock( &m_guiMutex );
}
Fl::flush();
@@ -271,15 +260,6 @@ int main( int _argc, char * * _argv )
const auto pollParentThread = PollParentThread{};
#endif
#ifdef LMMS_BUILD_WIN32
#ifndef __WINPTHREADS_VERSION
// (non-portable) initialization of statically linked pthread library
pthread_win32_process_attach_np();
pthread_win32_thread_attach_np();
#endif
#endif // LMMS_BUILD_WIN32
#ifdef SYNC_WITH_SHM_FIFO
RemoteZynAddSubFx * remoteZASF =
new RemoteZynAddSubFx( _argv[1], _argv[2] );
@@ -291,14 +271,6 @@ int main( int _argc, char * * _argv )
delete remoteZASF;
#ifdef LMMS_BUILD_WIN32
#ifndef __WINPTHREADS_VERSION
pthread_win32_thread_detach_np();
pthread_win32_process_detach_np();
#endif
#endif // LMMS_BUILD_WIN32
return 0;
}

View File

@@ -0,0 +1,9 @@
#include <condition_variable>
#include <mutex>
#include <thread>
#if defined(__MINGW32__) && !defined(_GLIBCXX_HAS_GTHREADS)
# include <mingw.condition_variable.h>
# include <mingw.mutex.h>
# include <mingw.thread.h>
#endif