Skip to content

Commit

Permalink
Support ZynAddSubFx with MSVC (LMMS#6561)
Browse files Browse the repository at this point in the history
  • Loading branch information
DomClark authored and sakertooth committed May 30, 2023
1 parent 4c1d0a7 commit c67d8ca
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 137 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,8 @@ jobs:
--triplet=${{ matrix.arch }}-windows `
--host-triplet=${{ matrix.arch }}-windows `
--recurse `
fftw3 fluidsynth[sndfile] libsamplerate libsndfile libstk lilv lv2 `
portaudio sdl2
fftw3 fltk fluidsynth[sndfile] libsamplerate libsndfile libstk `
lilv lv2 portaudio sdl2
- name: Set up build environment
uses: ilammy/msvc-dev-cmd@d8610e2b41c6d0f0c3b4c46dad8df0fd826c68e1
with:
Expand Down
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,13 @@ ENDIF(WANT_JACK)
FIND_PACKAGE(FFTW COMPONENTS fftw3f REQUIRED)

# check for FLTK
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()
FIND_PACKAGE(FLTK)
IF(FLTK_FOUND)
SET(STATUS_ZYN "OK")
Expand Down
1 change: 0 additions & 1 deletion cmake/modules/PluginList.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ ENDIF()
IF(MSVC)
SET(MSVC_INCOMPATIBLE_PLUGINS
LadspaEffect
ZynAddSubFx
)
message(WARNING "Compiling with MSVC. The following plugins are not available: ${MSVC_INCOMPATIBLE_PLUGINS}")
LIST(REMOVE_ITEM PLUGIN_LIST ${MSVC_INCOMPATIBLE_PLUGINS})
Expand Down
6 changes: 3 additions & 3 deletions include/IoHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ namespace lmms

#ifdef _WIN32

std::wstring toWString(const std::string& s)
inline std::wstring toWString(const std::string& s)
{
std::wstring ret;
int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(),
Expand All @@ -64,7 +64,7 @@ std::wstring toWString(const std::string& s)
#endif


FILE* F_OPEN_UTF8(std::string const& fname, const char* mode){
inline FILE* F_OPEN_UTF8(std::string const& fname, const char* mode){
#ifdef LMMS_BUILD_WIN32
return _wfopen(toWString(fname).data(), toWString(mode).data());
#else
Expand All @@ -73,7 +73,7 @@ FILE* F_OPEN_UTF8(std::string const& fname, const char* mode){
}


int fileToDescriptor(FILE* f, bool closeFile = true)
inline int fileToDescriptor(FILE* f, bool closeFile = true)
{
int fh;
if (f == nullptr) {return -1;}
Expand Down
114 changes: 50 additions & 64 deletions plugins/ZynAddSubFx/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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()
Expand All @@ -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)
Expand Down Expand Up @@ -116,24 +105,23 @@ SET(zynaddsubfx_core_SRCS
zynaddsubfx/src/Synth/PADnote.cpp
zynaddsubfx/src/Synth/Resonance.cpp
zynaddsubfx/src/Synth/SUBnote.cpp
)


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)
)

add_library(ZynAddSubFxCoreObjs OBJECT LocalZynAddSubFx.cpp ${zynaddsubfx_core_SRCS})
add_library(ZynAddSubFxCore INTERFACE)
target_sources(ZynAddSubFxCore INTERFACE
$<TARGET_OBJECTS:ZynAddSubFxCoreObjs>
$<TARGET_OBJECTS:zynaddsubfx_nio>
)

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)
Expand All @@ -144,25 +132,31 @@ 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}"
"-I\"${CMAKE_CURRENT_SOURCE_DIR}\""
"-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")
Expand All @@ -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)
Expand All @@ -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
Expand Down
50 changes: 30 additions & 20 deletions plugins/ZynAddSubFx/LocalZynAddSubFx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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 );
}

Expand All @@ -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();

Expand Down Expand Up @@ -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 );

Expand Down
Loading

0 comments on commit c67d8ca

Please sign in to comment.