diff --git a/.gitmodules b/.gitmodules index 3f4859b56d9..2ff7255bfad 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,7 +6,8 @@ url = https://github.com/rampantpixels/rpmalloc.git [submodule "plugins/zynaddsubfx/zynaddsubfx"] path = plugins/zynaddsubfx/zynaddsubfx - url = https://github.com/lmms/zynaddsubfx.git + url = https://github.com/justnope/zynaddsubfx.git + branch = msvc/ng [submodule "plugins/FreeBoy/game-music-emu"] path = plugins/FreeBoy/game-music-emu url = https://bitbucket.org/mpyne/game-music-emu.git diff --git a/CMakeLists.txt b/CMakeLists.txt index d2123ac15fe..924dbf3543f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,9 @@ ENDIF() INCLUDE(VersionInfo) INCLUDE(DetectMachine) +IF(CMAKE_TOOLCHAIN_FILE MATCHES "vcpkg.cmake$") + SET(USING_VCPKG TRUE) +ENDIF() OPTION(WANT_ALSA "Include ALSA (Advanced Linux Sound Architecture) support" ON) OPTION(WANT_CALF "Include CALF LADSPA plugins" ON) @@ -86,9 +89,7 @@ ENDIF(LMMS_BUILD_APPLE) IF(LMMS_BUILD_WIN32) SET(WANT_ALSA OFF) - SET(WANT_JACK OFF) SET(WANT_PULSEAUDIO OFF) - SET(WANT_PORTAUDIO OFF) SET(WANT_SOUNDIO OFF) SET(WANT_WINMM ON) SET(LMMS_HAVE_WINMM TRUE) @@ -166,10 +167,15 @@ FIND_PACKAGE(Qt5Test) SET(QT_QTTEST_LIBRARY Qt5::Test) # check for libsndfile -PKG_CHECK_MODULES(SNDFILE REQUIRED sndfile>=1.0.18) -IF(NOT SNDFILE_FOUND) - MESSAGE(FATAL_ERROR "LMMS requires libsndfile1 and libsndfile1-dev >= 1.0.18 - please install, remove CMakeCache.txt and try again!") -ENDIF() +IF(USING_VCPKG) + FIND_PACKAGE(LibSndFile 1.0.18 REQUIRED) + SET(SNDFILE_LIBRARIES sndfile-shared) +ELSE(USING_VCPKG) + PKG_CHECK_MODULES(SNDFILE REQUIRED sndfile>=1.0.18) + IF(NOT SNDFILE_FOUND) + MESSAGE(FATAL_ERROR "LMMS requires libsndfile1 and libsndfile1-dev >= 1.0.18 - please install, remove CMakeCache.txt and try again!") + ENDIF() +ENDIF(USING_VCPKG) # check if we can use SF_SET_COMPRESSION_LEVEL IF(NOT SNDFILE_VERSION VERSION_LESS 1.0.26) SET(LMMS_HAVE_SF_COMPLEVEL TRUE) @@ -373,32 +379,60 @@ ENDIF(NOT LMMS_HAVE_ALSA) # check for JACK IF(WANT_JACK) - PKG_CHECK_MODULES(JACK jack>=0.77) - IF(JACK_FOUND) - IF(WANT_WEAKJACK) - SET(LMMS_HAVE_WEAKJACK TRUE) - SET(WEAKJACK_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/3rdparty/weakjack/weakjack) - SET(STATUS_JACK "OK (weak linking enabled)") - SET(JACK_INCLUDE_DIRS "") - # use dlsym instead - SET(JACK_LIBRARIES ${CMAKE_DL_LIBS}) - ELSE() - SET(STATUS_JACK "OK") - ENDIF() + #TODO: quick hack to enable jack for windows. remove and implement it better. + #Do not use jack2 from vcpkg, uninstall if you have it (header file defines uint8_t etc...) + IF(MSVC) + #this is the jack common dir if you got it from git + SET(JACK_INCLUDE_DIRS "" CACHE PATH "Jack2 path") + #This is in the jack build dir common/jack.lib again if from git + SET(JACK_LIBRARIES "" CACHE FILEPATH "jack2 library path") + #again, quick hack. Get the jack dll for installing its in build/common/libjack-0.dll + SET(JACK_LIBRARY_DLL "" CACHE FILEPATH "jack2 library dll") + + SET(JACK_FOUND TRUE) SET(LMMS_HAVE_JACK TRUE) - ELSE(JACK_FOUND) - SET(STATUS_JACK "not found, please install libjack0.100.0-dev (or similar) " - "if you require JACK support") - ENDIF(JACK_FOUND) + ELSE(MSVC) + PKG_CHECK_MODULES(JACK jack>=0.77) + IF(JACK_FOUND) + IF(WANT_WEAKJACK) + SET(LMMS_HAVE_WEAKJACK TRUE) + SET(WEAKJACK_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/3rdparty/weakjack/weakjack) + SET(STATUS_JACK "OK (weak linking enabled)") + SET(JACK_INCLUDE_DIRS "") + # use dlsym instead + SET(JACK_LIBRARIES ${CMAKE_DL_LIBS}) + ELSE() + SET(STATUS_JACK "OK") + ENDIF() + SET(LMMS_HAVE_JACK TRUE) + ELSE(JACK_FOUND) + SET(STATUS_JACK "not found, please install libjack0.100.0-dev (or similar) " + "if you require JACK support") + ENDIF(JACK_FOUND) + ENDIF(MSVC) ENDIF(WANT_JACK) # check for FFTW3F-library -PKG_CHECK_MODULES(FFTW3F REQUIRED fftw3f>=3.0.0) - +IF(USING_VCPKG) + #currently find_package for fftw is broken in vcpkg. Replace this when fixed + FIND_PATH(FFTW3F_INCLUDE_DIRS fftw3.h) + FIND_LIBRARY(FFTW3F_LIBRARIES fftw3f) +ELSE(USING_VCPKG) + PKG_CHECK_MODULES(FFTW3F REQUIRED fftw3f>=3.0.0) +ENDIF(USING_VCPKG) # check for FLTK -FIND_PACKAGE(FLTK) +IF(USING_VCPKG) + FIND_PATH(FLTK_INCLUDE_DIR "fl/fl.h") + FIND_LIBRARY(FLTK_LIBRARIES "fltk") + FIND_PROGRAM(FLTK_FLUID_EXECUTABLE "fluid") + IF(FLTK_INCLUDE_DIR) + SET(FLTK_FOUND TRUE) + ENDIF(FLTK_INCLUDE_DIR) +ELSE(USING_PCPKG) + FIND_PACKAGE(FLTK) +ENDIF(USING_VCPKG) IF(FLTK_FOUND) SET(STATUS_ZYN "OK") ELSE() @@ -406,16 +440,27 @@ ELSE() ENDIF() # check for Fluidsynth -IF(WANT_SF2) - PKG_CHECK_MODULES(FLUIDSYNTH fluidsynth>=1.0.7) - IF(FLUIDSYNTH_FOUND) +#TODO: better impl +IF(USING_VCPKG) + FIND_FILE(FLUIDSYNTH_INCLUDE_DIRS "fluidsynth.h") + FIND_LIBRARY(FLUIDSYNTH_LIBRARIES "fluidsynth.lib") + IF(FLUIDSYNTH_INCLUDE_DIRS) + SET(FLUIDSYNTH_FOUND) SET(LMMS_HAVE_FLUIDSYNTH TRUE) SET(STATUS_FLUIDSYNTH "OK") - ELSE(FLUIDSYNTH_FOUND) - SET(STATUS_FLUIDSYNTH "not found, libfluidsynth-dev (or similar)" - "is highly recommended") - ENDIF(FLUIDSYNTH_FOUND) -ENDIF(WANT_SF2) + ENDIF(FLUIDSYNTH_INCLUDE_DIRS) +ELSE(USING_VCPKG) + IF(WANT_SF2) + PKG_CHECK_MODULES(FLUIDSYNTH fluidsynth>=1.0.7) + IF(FLUIDSYNTH_FOUND) + SET(LMMS_HAVE_FLUIDSYNTH TRUE) + SET(STATUS_FLUIDSYNTH "OK") + ELSE(FLUIDSYNTH_FOUND) + SET(STATUS_FLUIDSYNTH "not found, libfluidsynth-dev (or similar)" + "is highly recommended") + ENDIF(FLUIDSYNTH_FOUND) + ENDIF(WANT_SF2) +ENDIF(USING_VCPKG) # check for libgig If(WANT_GIG) @@ -477,7 +522,13 @@ ELSE() ENDIF(WANT_DEBUG_FPE) # check for libsamplerate -PKG_CHECK_MODULES(SAMPLERATE REQUIRED samplerate>=0.1.8) +IF(USING_VCPKG) + #TODO no cmake config support. Can we check the version some other way? + FIND_FILE(SAMPLERATE_INCLUDE_DIRS samplerate.h) + FIND_LIBRARY(SAMPLERATE_LIBRARIES libsamplerate-0) +ELSE(USING_VCPKG) + PKG_CHECK_MODULES(SAMPLERATE REQUIRED samplerate>=0.1.8) +ENDIF(USING_VCPKG) # set compiler flags IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") @@ -700,4 +751,5 @@ MESSAGE( "-----------------------------------------------------------------\n" "\n\n") +SET(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION "${BIN_DIR}") INCLUDE(InstallRequiredSystemLibraries) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index ec6224e3536..16866e4d491 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -139,10 +139,10 @@ fi # Move executables so linuxdeployqt can find them ZYNLIB="${APPDIR}usr/lib/lmms/RemoteZynAddSubFx" -VSTLIB="${APPDIR}usr/lib/lmms/RemoteVstPlugin.exe.so" +VSTLIB="${APPDIR}usr/lib/lmms/RemoteVstPlugin32.exe.so" ZYNBIN="${APPDIR}usr/bin/RemoteZynAddSubFx" -VSTBIN="${APPDIR}usr/bin/RemoteVstPlugin.exe.so" +VSTBIN="${APPDIR}usr/bin/RemoteVstPlugin32.exe.so" mv "$ZYNLIB" "$ZYNBIN" mv "$VSTLIB" "$VSTBIN" diff --git a/cmake/modules/FindPortaudio.cmake b/cmake/modules/FindPortaudio.cmake index bb6bdf48b24..61a7cb4fb9e 100644 --- a/cmake/modules/FindPortaudio.cmake +++ b/cmake/modules/FindPortaudio.cmake @@ -13,24 +13,31 @@ # -if (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS) - # in cache already - set(PORTAUDIO_FOUND TRUE) -else (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS) - include(FindPkgConfig) - pkg_check_modules(PORTAUDIO portaudio-2.0) - if (PORTAUDIO_FOUND) - if (NOT Portaudio_FIND_QUIETLY) - message(STATUS "Found Portaudio: ${PORTAUDIO_LIBRARIES}") - endif (NOT Portaudio_FIND_QUIETLY) - else (PORTAUDIO_FOUND) - if (Portaudio_FIND_REQUIRED) - message(FATAL_ERROR "Could not find Portaudio") - endif (Portaudio_FIND_REQUIRED) - endif (PORTAUDIO_FOUND) +IF(PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS) + # in cache already + set(PORTAUDIO_FOUND TRUE) +ELSE(PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS) + IF(USING_VCPKG) + FIND_FILE(PORTAUDIO_INCLUDE_DIRS "portaudio.h") + FIND_LIBRARY(PORTAUDIO_LIBRARIES "portaudio.lib") + IF(PORTAUDIO_INCLUDE_DIRS) + SET(PORTAUDIO_FOUND TRUE) + ENDIF(PORTAUDIO_INCLUDE_DIRS) + ELSE(USING_VCPKG) + include(FindPkgConfig) + pkg_check_modules(PORTAUDIO portaudio-2.0) + if (PORTAUDIO_FOUND) + if (NOT Portaudio_FIND_QUIETLY) + message(STATUS "Found Portaudio: ${PORTAUDIO_LIBRARIES}") + endif (NOT Portaudio_FIND_QUIETLY) + else (PORTAUDIO_FOUND) + if (Portaudio_FIND_REQUIRED) + message(FATAL_ERROR "Could not find Portaudio") + endif (Portaudio_FIND_REQUIRED) + endif (PORTAUDIO_FOUND) - # show the PORTAUDIO_INCLUDE_DIRS and PORTAUDIO_LIBRARIES variables only in the advanced view - mark_as_advanced(PORTAUDIO_INCLUDE_DIRS PORTAUDIO_LIBRARIES) - -endif (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS) + # show the PORTAUDIO_INCLUDE_DIRS and PORTAUDIO_LIBRARIES variables only in the advanced view + mark_as_advanced(PORTAUDIO_INCLUDE_DIRS PORTAUDIO_LIBRARIES) + ENDIF(USING_VCPKG) +ENDIF(PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS) diff --git a/cmake/nsis/CMakeLists.txt b/cmake/nsis/CMakeLists.txt index b21c920e5c3..87668d32b0b 100644 --- a/cmake/nsis/CMakeLists.txt +++ b/cmake/nsis/CMakeLists.txt @@ -1,4 +1,7 @@ SET(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/nsis_branding.bmp") +IF(MSVC) + STRING(REPLACE "/" "\\\\" CPACK_PACKAGE_ICON ${CPACK_PACKAGE_ICON}) +ENDIF(MSVC) SET(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/lmms.ico") SET(CPACK_NSIS_INSTALLED_ICON_NAME "${CMAKE_PROJECT_NAME}.exe" PARENT_SCOPE) SET(CPACK_NSIS_DISPLAY_NAME "${PROJECT_NAME_UCASE} ${VERSION}" PARENT_SCOPE) @@ -8,7 +11,8 @@ SET(CPACK_NSIS_CONTACT "${PROJECT_EMAIL}" PARENT_SCOPE) SET(CPACK_PACKAGE_EXECUTABLES "${CMAKE_PROJECT_NAME}.exe;${PROJECT_NAME_UCASE}" PARENT_SCOPE) SET(CPACK_NSIS_MENU_LINKS "${CMAKE_PROJECT_NAME}.exe;${PROJECT_NAME_UCASE}" PARENT_SCOPE) SET(CPACK_NSIS_DEFINES " - !include ${CMAKE_SOURCE_DIR}/cmake/nsis/FileAssociation.nsh + !addincludedir ${CMAKE_SOURCE_DIR}/cmake/nsis + !include FileAssociation.nsh !include LogicLib.nsh !include WinVer.nsh") SET(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}-win32") diff --git a/data/locale/CMakeLists.txt b/data/locale/CMakeLists.txt index 3c72e7d787d..9a772640640 100644 --- a/data/locale/CMakeLists.txt +++ b/data/locale/CMakeLists.txt @@ -26,7 +26,7 @@ FOREACH(_ts_file ${lmms_LOCALES}) STRING(REPLACE ".ts" ".qm" _qm_file "${_ts_file}") STRING(REPLACE ".ts" ".qm" _qm_target "${_ts_target}") ADD_CUSTOM_TARGET(${_ts_target} - COMMAND "${QT_LUPDATE_EXECUTABLE}" -locations none -no-obsolete -I ${CMAKE_SOURCE_DIR}/include/ ${LMMS_SRCS} ${LMMS_INCLUDES} ${LMMS_UIS} `find "\"${CMAKE_SOURCE_DIR}/plugins/\"" -type f -name '*.cpp' -or -name '*.h'` -ts "\"${_ts_file}\"" + COMMAND "${QT_LUPDATE_EXECUTABLE}" -locations none -no-obsolete -I ${CMAKE_SOURCE_DIR}/include/ ${LMMS_SRCS} ${LMMS_UIS} ${CMAKE_SOURCE_DIR}/plugins -ts "\"${_ts_file}\"" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) ADD_CUSTOM_TARGET(${_qm_target} COMMAND "${QT_LRELEASE_EXECUTABLE}" "${_ts_file}" -qm "${_qm_file}" diff --git a/include/AudioJack.h b/include/AudioJack.h index 83717f251ee..8af8c782e5c 100644 --- a/include/AudioJack.h +++ b/include/AudioJack.h @@ -54,12 +54,6 @@ class AudioJack : public QObject, public AudioDevice AudioJack( bool & _success_ful, Mixer* mixer ); virtual ~AudioJack(); - // this is to allow the jack midi connection to use the same jack client connection - // the jack callback is handled here, we call the midi client so that it can read - // it's midi data during the callback - AudioJack * addMidiClient(MidiJack *midiClient); - jack_client_t * jackClient() {return m_client;}; - inline static QString name() { return QT_TRANSLATE_NOOP( "setupWidget", @@ -78,7 +72,6 @@ class AudioJack : public QObject, public AudioDevice private: QLineEdit * m_clientName; LcdSpinBox * m_channels; - } ; @@ -110,7 +103,6 @@ private slots: bool m_stopped; QMutex m_processingMutex; - MidiJack *m_midiClient; QVector m_outputPorts; jack_default_audio_sample_t * * m_tempOutBufs; surroundSampleFrame * m_outBuf; diff --git a/include/AudioSdl.h b/include/AudioSdl.h index 11942efda88..2fe5432352d 100644 --- a/include/AudioSdl.h +++ b/include/AudioSdl.h @@ -1,26 +1,26 @@ /* - * AudioSdl.h - device-class that performs PCM-output via SDL - * - * Copyright (c) 2004-2009 Tobias Doerffel - * - * This file is part of LMMS - https://lmms.io - * - * 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. - * - */ +* AudioSdl.h - device-class that performs PCM-output via SDL +* +* Copyright (c) 2004-2009 Tobias Doerffel +* +* This file is part of LMMS - https://lmms.io +* +* 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 AUDIO_SDL_H #define AUDIO_SDL_H @@ -46,20 +46,20 @@ class QLineEdit; class AudioSdl : public AudioDevice { public: - AudioSdl( bool & _success_ful, Mixer* mixer ); + AudioSdl(bool & _success_ful, Mixer* mixer); virtual ~AudioSdl(); inline static QString name() { - return QT_TRANSLATE_NOOP( "setupWidget", - "SDL (Simple DirectMedia Layer)" ); + return QT_TRANSLATE_NOOP("setupWidget", + "SDL (Simple DirectMedia Layer)"); } class setupWidget : public AudioDeviceSetupWidget { public: - setupWidget( QWidget * _parent ); + setupWidget(QWidget * _parent); virtual ~setupWidget(); virtual void saveSettings(); @@ -67,7 +67,7 @@ class AudioSdl : public AudioDevice private: QLineEdit * m_device; - } ; + }; private: @@ -75,21 +75,39 @@ class AudioSdl : public AudioDevice virtual void stopProcessing(); virtual void applyQualitySettings(); - static void sdlAudioCallback( void * _udata, Uint8 * _buf, int _len ); - void sdlAudioCallback( Uint8 * _buf, int _len ); + static void sdlAudioCallback(void * _udata, Uint8 * _buf, int _len); + void sdlAudioCallback(Uint8 * _buf, int _len); + +#ifdef LMMS_HAVE_SDL2 + static void sdlInputAudioCallback(void * _udata, Uint8 * _buf, int _len); + void sdlInputAudioCallback(Uint8 * _buf, int _len); +#endif SDL_AudioSpec m_audioHandle; surroundSampleFrame * m_outBuf; + +#ifdef LMMS_HAVE_SDL2 + uint64_t m_currentBufferFramePos; + uint64_t m_currentBufferFramesCount; +#else Uint8 * m_convertedBuf; int m_convertedBufPos; int m_convertedBufSize; + bool m_outConvertEndian; +#endif - bool m_convertEndian; bool m_stopped; -} ; +#ifdef LMMS_HAVE_SDL2 + SDL_AudioDeviceID m_outputDevice; + + SDL_AudioSpec m_inputAudioHandle; + SDL_AudioDeviceID m_inputDevice; +#endif + +}; #endif diff --git a/include/MidiJack.h b/include/MidiJack.h index 8ebb6925f51..9c42b1056b8 100644 --- a/include/MidiJack.h +++ b/include/MidiJack.h @@ -38,10 +38,12 @@ #include #include #include - +#include +#include #include "MidiClient.h" #include "AudioJack.h" + #define JACK_MIDI_BUFFER_MAX 64 /* events */ class QLineEdit; @@ -52,7 +54,7 @@ class MidiJack : public QThread, public MidiClientRaw public: MidiJack(); virtual ~MidiJack(); - + jack_client_t* jackClient(); static QString probeDevice(); @@ -79,20 +81,16 @@ class MidiJack : public QThread, public MidiClientRaw private: - AudioJack *m_jackAudio; + //TODO: (experimental) replace this with a more efficient way + //also don't use sendByte but processOutEvent to get timings + std::mutex m_bufferLock; + std::vector m_midibuffer; + jack_client_t *m_jackClient; jack_port_t *m_input_port; jack_port_t *m_output_port; - uint8_t m_jack_buffer[JACK_MIDI_BUFFER_MAX * 4]; - - void JackMidiOutEvent(uint8_t *buf, uint8_t len); - void lock(); - void unlock(); - - void getPortInfo( const QString& sPortName, int& nClient, int& nPort ); volatile bool m_quit; - }; #endif // LMMS_HAVE_JACK diff --git a/include/stdshims.h b/include/stdshims.h index 456d31607dc..85c4f457aab 100644 --- a/include/stdshims.h +++ b/include/stdshims.h @@ -7,8 +7,10 @@ #include #include -#if (__cplusplus >= 201402L) +#if (__cplusplus >= 201402L || _MSC_VER) +#ifndef _MSC_VER #warning "This file should now be removed! The functions it provides are part of the C++14 standard." +#endif using std::make_unique; #else diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index d6b649bfdf8..b47f5d49d1a 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -91,14 +91,6 @@ ENDIF("${PLUGIN_LIST}" STREQUAL "") IF(MSVC) SET(MSVC_INCOMPATIBLE_PLUGINS LadspaEffect - monstro - organic - ReverbSC - sid - vibed - VstEffect - Xpressive - zynaddsubfx ) message(WARNING "Compiling with MSVC. The following plugins are not available: ${MSVC_INCOMPATIBLE_PLUGINS}") LIST(REMOVE_ITEM PLUGIN_LIST ${MSVC_INCOMPATIBLE_PLUGINS}) diff --git a/plugins/ReverbSC/revsc.c b/plugins/ReverbSC/revsc.c index 35084c175e4..4092bfb795b 100644 --- a/plugins/ReverbSC/revsc.c +++ b/plugins/ReverbSC/revsc.c @@ -72,7 +72,7 @@ int sp_revsc_init(sp_data *sp, sp_revsc *p) sp_auxdata_alloc(&p->aux, nBytes); nBytes = 0; for (i = 0; i < 8; i++) { - p->delayLines[i].buf = (p->aux.ptr) + nBytes; + p->delayLines[i].buf = (char*)(p->aux.ptr) + nBytes; init_delay_line(p, &p->delayLines[i], i); nBytes += delay_line_bytes_alloc(sp->sr, 1, i); } diff --git a/plugins/VstEffect/CMakeLists.txt b/plugins/VstEffect/CMakeLists.txt index 78d8e64835a..e189cb99515 100644 --- a/plugins/VstEffect/CMakeLists.txt +++ b/plugins/VstEffect/CMakeLists.txt @@ -11,7 +11,9 @@ ELSE() ENDIF() BUILD_PLUGIN(vsteffect VstEffect.cpp VstEffectControls.cpp VstEffectControlDialog.cpp VstSubPluginFeatures.cpp VstEffect.h VstEffectControls.h VstEffectControlDialog.h VstSubPluginFeatures.h MOCFILES VstEffectControlDialog.h VstEffectControls.h EMBEDDED_RESOURCES *.png) +IF(NOT MSVC) SET_TARGET_PROPERTIES(vsteffect PROPERTIES COMPILE_FLAGS "-Wno-attributes") +ENDIF(NOT MSVC) TARGET_LINK_LIBRARIES(vsteffect vstbase) ENDIF(LMMS_SUPPORT_VST) diff --git a/plugins/VstEffect/VstEffectControls.cpp b/plugins/VstEffect/VstEffectControls.cpp index 92688545be2..557dabc5e1a 100644 --- a/plugins/VstEffect/VstEffectControls.cpp +++ b/plugins/VstEffect/VstEffectControls.cpp @@ -23,6 +23,7 @@ */ #include +#include #include "VstEffectControls.h" #include "VstEffect.h" @@ -198,7 +199,7 @@ void VstEffectControls::updateMenu( void ) QMenu * to_menu = m_selPresetButton->menu(); to_menu->clear(); - QAction *presetActions[list1.size()]; + std::vector presetActions(list1.size()); for (int i = 0; i < list1.size(); i++) { presetActions[i] = new QAction(this); diff --git a/plugins/Xpressive/CMakeLists.txt b/plugins/Xpressive/CMakeLists.txt index 6745c71d5bf..1b550ae29c3 100644 --- a/plugins/Xpressive/CMakeLists.txt +++ b/plugins/Xpressive/CMakeLists.txt @@ -8,11 +8,16 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dexprtk_disable_comments") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dexprtk_disable_string_capabilities") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dexprtk_disable_rtl_io_file") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dexprtk_disable_rtl_vecops") -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WERROR_FLAGS} -fexceptions") -IF(LMMS_BUILD_WIN32 AND NOT MSVC) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -Dexprtk_disable_enhanced_features") -ENDIF() +IF(MSVC) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") +ELSE(MSVC) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WERROR_FLAGS} -fexceptions") + + IF(LMMMS_BUILD_WIN32) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -Dexprtk_disable_enhanced_features") + ENDIF(LMMS_BUILD_WIN32) +ENDIF(MSVC) BUILD_PLUGIN(xpressive Xpressive.cpp diff --git a/plugins/Xpressive/Xpressive.cpp b/plugins/Xpressive/Xpressive.cpp index f424e989452..14c72179ed2 100644 --- a/plugins/Xpressive/Xpressive.cpp +++ b/plugins/Xpressive/Xpressive.cpp @@ -49,6 +49,9 @@ #include "ExprSynth.h" #include "plugin_export.h" +#ifdef LMMS_BUILD_WIN32 +#include +#endif extern "C" { @@ -876,11 +879,25 @@ void XpressiveView::helpClicked() { } +#ifdef LMMS_BUILD_WIN32 +//TODO: s_instance already gets deleted when the parent is deleted +//I'm leaving this code here in case I'm mistaken because the same should go +//for the linux implementation, but can't test it. + +//BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +//{ +// if (fdwReason == DLL_PROCESS_DETACH) +// { +// XpressiveHelpView::finalize(); +// } +// return TRUE; +//} +#else __attribute__((destructor)) static void module_destroy() { XpressiveHelpView::finalize(); } - +#endif extern "C" { // necessary for getting instance out of shared lib diff --git a/plugins/carlabase/carla.h b/plugins/carlabase/carla.h index 6431e5300de..175a570d6ac 100644 --- a/plugins/carlabase/carla.h +++ b/plugins/carlabase/carla.h @@ -26,9 +26,9 @@ #define CARLA_H #include +#include "plugin_export.h" #include "CarlaNative.h" - #include "Instrument.h" #include "InstrumentView.h" diff --git a/plugins/monstro/Monstro.cpp b/plugins/monstro/Monstro.cpp index e8f00d7c0b3..3a108a1b291 100644 --- a/plugins/monstro/Monstro.cpp +++ b/plugins/monstro/Monstro.cpp @@ -24,7 +24,7 @@ #include - +#include #include "Monstro.h" #include "Engine.h" #include "InstrumentTrack.h" @@ -341,9 +341,9 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) float sub; // modulators - float lfo[2][ m_parent->m_fpp ]; - float env[2][ m_parent->m_fpp ]; - + std::vector lfo[2] = { std::vector(m_parent->m_fpp), std::vector(m_parent->m_fpp) }; + std::vector env[2] = { std::vector(m_parent->m_fpp), std::vector(m_parent->m_fpp) }; + // render modulators: envelopes, lfos updateModulators( &env[0][0], &env[1][0], &lfo[0][0], &lfo[1][0], _frames ); diff --git a/plugins/organic/organic.cpp b/plugins/organic/organic.cpp index a5b8c132982..b7db0182d97 100644 --- a/plugins/organic/organic.cpp +++ b/plugins/organic/organic.cpp @@ -21,14 +21,12 @@ * Boston, MA 02110-1301 USA. * */ - - #include "organic.h" - #include #include +#include #include "Engine.h" #include "InstrumentTrack.h" @@ -233,8 +231,8 @@ void organicInstrument::playNote( NotePlayHandle * _n, if( _n->totalFramesPlayed() == 0 || _n->m_pluginData == NULL ) { - Oscillator * oscs_l[m_numOscillators]; - Oscillator * oscs_r[m_numOscillators]; + std::vector oscs_l(m_numOscillators); + std::vector oscs_r(m_numOscillators); _n->m_pluginData = new oscPtr; diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index 1cfd6ae0b2e..52fb43e357f 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -27,7 +27,7 @@ #include #include #include - +#include #include "ConfigManager.h" #include "FileDialog.h" #include "sf2_player.h" @@ -603,10 +603,12 @@ void sf2Instrument::noteOn( SF2PluginData * n ) // get list of current voice IDs so we can easily spot the new // voice after the fluid_synth_noteon() call - const int poly = fluid_synth_get_polyphony( m_synth ); - fluid_voice_t * voices[poly]; - unsigned int id[poly]; - fluid_synth_get_voicelist( m_synth, voices, poly, -1 ); + + size_t poly = fluid_synth_get_polyphony( m_synth ); + std::vectorvoices(poly); + std::vectorid(poly); + + fluid_synth_get_voicelist( m_synth, voices.data(), poly, -1 ); for( int i = 0; i < poly; ++i ) { id[i] = 0; @@ -619,7 +621,7 @@ void sf2Instrument::noteOn( SF2PluginData * n ) fluid_synth_noteon( m_synth, m_channel, n->midiNote, n->lastVelocity ); // get new voice and save it - fluid_synth_get_voicelist( m_synth, voices, poly, -1 ); + fluid_synth_get_voicelist( m_synth, voices.data(), poly, -1 ); for( int i = 0; i < poly && voices[i]; ++i ) { const unsigned int newID = fluid_voice_get_id( voices[i] ); diff --git a/plugins/sid/sid_instrument.cpp b/plugins/sid/sid_instrument.cpp index d33b7b73601..b4e223c1289 100644 --- a/plugins/sid/sid_instrument.cpp +++ b/plugins/sid/sid_instrument.cpp @@ -29,6 +29,7 @@ #include #include +#include #include "sid.h" @@ -324,7 +325,7 @@ void sidInstrument::playNote( NotePlayHandle * _n, cSID *sid = static_cast( _n->m_pluginData ); int delta_t = clockrate * frames / samplerate + 4; - short buf[frames]; + std::vector buf(frames); unsigned char sidreg[NUMSIDREGS]; for (int c = 0; c < NUMSIDREGS; c++) @@ -425,7 +426,7 @@ void sidInstrument::playNote( NotePlayHandle * _n, sidreg[24] = data8&0x00FF; - int num = sid_fillbuffer(sidreg, sid,delta_t,buf, frames); + int num = sid_fillbuffer(sidreg, sid,delta_t,buf.data(), frames); if(num!=frames) printf("!!!Not enough samples\n"); diff --git a/plugins/vibed/vibrating_string.cpp b/plugins/vibed/vibrating_string.cpp index a2080a69c07..b6b35a7f12b 100644 --- a/plugins/vibed/vibrating_string.cpp +++ b/plugins/vibed/vibrating_string.cpp @@ -56,7 +56,7 @@ vibratingString::vibratingString( float _pitch, int pick = static_cast( ceil( string_length * _pick ) ); - if( not _state ) + if( !_state ) { m_impulse = new float[string_length]; resample( _impulse, _len, string_length ); diff --git a/plugins/vibed/vibrating_string.h b/plugins/vibed/vibrating_string.h index 06358501f7c..3739d19a9a8 100644 --- a/plugins/vibed/vibrating_string.h +++ b/plugins/vibed/vibrating_string.h @@ -121,7 +121,7 @@ class vibratingString float r; float offset; - if( not _state ) + if( ! _state ) { for( int i = 0; i < _pick; i++ ) { diff --git a/plugins/vst_base/CMakeLists.txt b/plugins/vst_base/CMakeLists.txt index 943631b92a6..90570730f4d 100644 --- a/plugins/vst_base/CMakeLists.txt +++ b/plugins/vst_base/CMakeLists.txt @@ -24,7 +24,6 @@ SET(EXTERNALPROJECT_CMAKE_ARGS "-DLMMS_SOURCE_DIR=${CMAKE_SOURCE_DIR}" "-DLMMS_BINARY_DIR=${CMAKE_BINARY_DIR}" "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" - "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" "-DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}" "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" ) @@ -33,29 +32,23 @@ SET(EXTERNALPROJECT_CMAKE_ARGS IF(LMMS_BUILD_WIN32 AND NOT LMMS_BUILD_WIN64) ADD_SUBDIRECTORY(RemoteVstPlugin) ELSEIF(LMMS_BUILD_WIN64 AND MSVC) - SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION}) + STRING(REPLACE " Win64" "" GENERATOR ${CMAKE_GENERATOR}) - IF(MSVC_VER VERSION_GREATER 19.0 OR MSVC_VER VERSION_EQUAL 19.0) - SET(GENERATOR "Visual Studio 14 2015") - SET(MSVC_YEAR 2015) - ELSEIF(MSVC_VER VERSION_EQUAL 19.10 OR MSVC_VER VERSION_EQUAL 19.10) - SET(GENERATOR "Visual Studio 15 2017") - SET(MSVC_YEAR 2017) - ELSE() - MESSAGE(SEND_ERROR "Can't build RemoteVstPlugin32, unknown MSVC version ${MSVC_VER}") - ENDIF() - - GET_FILENAME_COMPONENT(QT_BIN_DIR ${QT_QMAKE_EXECUTABLE} DIRECTORY) - SET(QT_32_PREFIX "${QT_BIN_DIR}/../../msvc${MSVC_YEAR}") - IF(NOT (IS_DIRECTORY ${QT_32_PREFIX} AND EXISTS ${QT_32_PREFIX}/bin/qmake.exe)) - MESSAGE(SEND_ERROR "Can't build RemoteVstPlugin32, no Qt 32 bit installation found at ${QT_32_PREFIX}") - ENDIF() + IF(NOT USING_VCPKG) + GET_FILENAME_COMPONENT(QT_BIN_DIR ${QT_QMAKE_EXECUTABLE} DIRECTORY) + SET(QT_32_PREFIX "${QT_BIN_DIR}/../../msvc${MSVC_YEAR}") + IF(NOT (IS_DIRECTORY ${QT_32_PREFIX} AND EXISTS ${QT_32_PREFIX}/bin/qmake.exe)) + MESSAGE(SEND_ERROR "Can't build RemoteVstPlugin32, no Qt 32 bit installation found at ${QT_32_PREFIX}") + ENDIF() + ENDIF(NOT USING_VCPKG) ExternalProject_Add(RemoteVstPlugin32 "${EXTERNALPROJECT_ARGS}" CMAKE_GENERATOR ${GENERATOR} + CMAKE_GENERATOR_TOOLSET ${CMAKE_GENERATOR_TOOLSET} CMAKE_ARGS "${EXTERNALPROJECT_CMAKE_ARGS}" + "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" "-DCMAKE_PREFIX_PATH=${QT_32_PREFIX}" ) ELSEIF(LMMS_BUILD_LINUX) @@ -82,6 +75,7 @@ ENDIF() # build 64 bit version of RemoteVstPlugin IF(LMMS_BUILD_WIN64) ADD_SUBDIRECTORY(RemoteVstPlugin) + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin64.exe" DESTINATION "${PLUGIN_DIR}") ELSEIF(LMMS_BUILD_LINUX) ExternalProject_Add(RemoteVstPlugin64 "${EXTERNALPROJECT_ARGS}" @@ -91,3 +85,23 @@ ELSEIF(LMMS_BUILD_LINUX) "-DCMAKE_CXX_FLAGS=-m64 -mwindows" ) ENDIF() + +IF(TARGET RemoteVstPlugin32) + IF(LMMS_BUILD_LINUX) + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}") + ELSEIF(LMMS_BUILD_WIN32) + IF(LMMS_BUILD_WIN64) + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32") + IF(USING_VCPKG) + SET(VCPKG_ROOT_32 "${CMAKE_FIND_ROOT_PATH}/../x86-windows") + + INSTALL(FILES "${VCPKG_ROOT_32}/bin/zlib1.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(FILES "${VCPKG_ROOT_32}/bin/pcre2-16.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(FILES "${VCPKG_ROOT_32}/bin/double-conversion.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(FILES "${VCPKG_ROOT_32}/bin/qt5core.dll" DESTINATION "${PLUGIN_DIR}/32") + ENDIF(USING_VCPKG) + ELSE(LMMS_BUILD_WIN64) + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}") + ENDIF(LMMS_BUILD_WIN64) + ENDIF() +ENDIF() \ No newline at end of file diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 565009636b3..e76f699ce78 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -328,7 +328,7 @@ class RemoteVstPlugin : public RemotePluginClient } ; // callback used by plugin for being able to communicate with it's host - static VST_CALL_CONV intptr_t hostCallback( AEffect * _effect, int32_t _opcode, + static intptr_t VST_CALL_CONV hostCallback( AEffect * _effect, int32_t _opcode, int32_t _index, intptr_t _value, void * _ptr, float _opt ); @@ -1473,7 +1473,7 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode, case audioMasterVersion: SHOW_CALLBACK( "amc: audioMasterVersion\n" ); - return 2300; + return 2400; case audioMasterCurrentId: SHOW_CALLBACK( "amc: audioMasterCurrentId\n" ); diff --git a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt index f6b3e9c4ead..1baf9406493 100644 --- a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt +++ b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt @@ -20,6 +20,11 @@ else() set(BITNESS 32) endif() +FOREACH( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} ) + STRING(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG) + SET("CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") +ENDFOREACH() + set(EXE_NAME RemoteVstPlugin${BITNESS}) add_executable(${EXE_NAME} ../RemoteVstPlugin.cpp diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index e629041ca02..b4a4a4935b4 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -104,12 +104,11 @@ VstPlugin::VstPlugin( const QString & _plugin ) : if( m_badDllFormat ) { m_badDllFormat = false; + tryLoad( "32/RemoteVstPlugin32" ); + } +#else + tryLoad("RemoteVstPlugin32"); #endif - tryLoad( "RemoteVstPlugin32" ); -#ifdef LMMS_BUILD_WIN64 - } -#endif - setTempo( Engine::getSong()->getTempo() ); connect( Engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ), diff --git a/plugins/zynaddsubfx/CMakeLists.txt b/plugins/zynaddsubfx/CMakeLists.txt index ff9d7219d28..f02ccd8db21 100644 --- a/plugins/zynaddsubfx/CMakeLists.txt +++ b/plugins/zynaddsubfx/CMakeLists.txt @@ -19,8 +19,15 @@ IF(LMMS_HOST_X86 OR LMMS_HOST_X86_64) ADD_DEFINITIONS(-DASM_F2I_YES) ENDIF(LMMS_HOST_X86 OR LMMS_HOST_X86_64) +#TODO: check if this is also necessary for linux +IF(MSVC) + FIND_LIBRARY(ZLIB_LIBRARIES zlib) +ENDIF(MSVC) + # build ZynAddSubFX with full optimizations +IF(NOT MSVC) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wno-misleading-indentation -Wno-write-strings -Wno-deprecated-declarations -fpermissive") +ENDIF() IF(LMMS_BUILD_WIN32) # link system-libraries @@ -118,10 +125,14 @@ SET(zynaddsubfx_core_SRCS IF(LMMS_BUILD_LINUX) ADD_LIBRARY(ZynAddSubFxCore MODULE LocalZynAddSubFx.cpp ${zynaddsubfx_core_SRCS}) ELSE() - ADD_LIBRARY(ZynAddSubFxCore SHARED LocalZynAddSubFx.cpp ${zynaddsubfx_core_SRCS}) + ADD_LIBRARY(ZynAddSubFxCore STATIC LocalZynAddSubFx.cpp ${zynaddsubfx_core_SRCS}) ENDIF() -TARGET_LINK_LIBRARIES(ZynAddSubFxCore zynaddsubfx_nio ${FFTW3F_LIBRARIES} ${QT_LIBRARIES} -lz -lpthread) +IF(MSVC) + TARGET_LINK_LIBRARIES(ZynAddSubFxCore zynaddsubfx_nio ${FFTW3F_LIBRARIES} ${QT_LIBRARIES} ${ZLIB_LIBRARIES}) +ELSE(MSVC) + TARGET_LINK_LIBRARIES(ZynAddSubFxCore zynaddsubfx_nio ${FFTW3F_LIBRARIES} ${QT_LIBRARIES} -lz -lpthread) +ENDIF(MSVC) # required libs for debug msys builds IF(LMMS_BUILD_MSYS AND CMAKE_BUILD_TYPE STREQUAL "Debug") TARGET_LINK_LIBRARIES(ZynAddSubFxCore QtCore4 QtGui4 QtXml4) @@ -131,7 +142,7 @@ 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}") + #INSTALL(TARGETS ZynAddSubFxCore RUNTIME DESTINATION "${PLUGIN_DIR}") ELSE(LMMS_BUILD_WIN32) INSTALL(TARGETS ZynAddSubFxCore LIBRARY DESTINATION "${PLUGIN_DIR}") ENDIF(LMMS_BUILD_WIN32) @@ -145,10 +156,10 @@ 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) +TARGET_LINK_LIBRARIES(zynaddsubfx ZynAddSubFxCore) ADD_DEPENDENCIES(zynaddsubfx ZynAddSubFxCore) -IF(WIN32) +IF(WIN32 AND NOT MSVC) SET(WINRC "${CMAKE_CURRENT_BINARY_DIR}/zynaddsubfxrc.obj") ADD_CUSTOM_COMMAND(OUTPUT "${WINRC}" COMMAND "${CMAKE_RC_COMPILER}" @@ -156,7 +167,7 @@ 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) @@ -173,7 +184,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 ) +TARGET_LINK_LIBRARIES(RemoteZynAddSubFx zynaddsubfx_gui ZynAddSubFxCore ${FLTK_FILTERED_LDFLAGS} -lpthread ) ADD_DEPENDENCIES(RemoteZynAddSubFx ZynAddSubFxCore) # Support qt_version_tag in Qt 5.6 diff --git a/plugins/zynaddsubfx/LocalZynAddSubFx.cpp b/plugins/zynaddsubfx/LocalZynAddSubFx.cpp index 0422751e950..e3e0156ec4e 100644 --- a/plugins/zynaddsubfx/LocalZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/LocalZynAddSubFx.cpp @@ -23,9 +23,8 @@ */ #include - +#include #include "zynaddsubfx/src/Misc/Util.h" -#include #include #include "LocalZynAddSubFx.h" @@ -53,7 +52,7 @@ LocalZynAddSubFx::LocalZynAddSubFx() : if( s_instanceCount == 0 ) { #ifdef LMMS_BUILD_WIN32 -#ifndef __WINPTHREADS_VERSION +#if !defined(__WINPTHREADS_VERSION) && !defined(_MSC_VER) // (non-portable) initialization of statically linked pthread library pthread_win32_process_attach_np(); pthread_win32_thread_attach_np(); @@ -142,10 +141,10 @@ void LocalZynAddSubFx::loadXML( const std::string & _filename ) { char * f = strdup( _filename.c_str() ); - pthread_mutex_lock( &m_master->mutex ); + m_master->mutex.lock(); m_master->defaults(); m_master->loadXML( f ); - pthread_mutex_unlock( &m_master->mutex ); + m_master->mutex.unlock(); m_master->applyparameters(); @@ -160,19 +159,16 @@ void LocalZynAddSubFx::loadPreset( const std::string & _filename, int _part ) { char * f = strdup( _filename.c_str() ); - pthread_mutex_lock( &m_master->mutex ); + m_master->mutex.lock(); m_master->part[_part]->defaultsinstrument(); m_master->part[_part]->loadXMLinstrument( f ); - pthread_mutex_unlock( &m_master->mutex ); + m_master->mutex.unlock(); m_master->applyparameters(); free( f ); } - - - void LocalZynAddSubFx::setPresetDir( const std::string & _dir ) { m_presetsDir = _dir; @@ -190,9 +186,6 @@ void LocalZynAddSubFx::setPresetDir( const std::string & _dir ) } } - - - void LocalZynAddSubFx::setLmmsWorkingDir( const std::string & _dir ) { if( config.workingDir != NULL ) @@ -204,8 +197,6 @@ void LocalZynAddSubFx::setLmmsWorkingDir( const std::string & _dir ) initConfig(); } - - void LocalZynAddSubFx::setPitchWheelBendRange( int semitones ) { for( int i = 0; i < NUM_MIDI_PARTS; ++i ) @@ -214,8 +205,6 @@ void LocalZynAddSubFx::setPitchWheelBendRange( int semitones ) } } - - void LocalZynAddSubFx::processMidiEvent( const MidiEvent& event ) { switch( event.type() ) @@ -256,15 +245,12 @@ void LocalZynAddSubFx::processMidiEvent( const MidiEvent& event ) } } - - - void LocalZynAddSubFx::processAudio( sampleFrame * _out ) { - float outputl[synth->buffersize]; - float outputr[synth->buffersize]; + std::vector outputl(synth->buffersize); + std::vector outputr(synth->buffersize); - m_master->GetAudioOutSamples( synth->buffersize, synth->samplerate, outputl, outputr ); + m_master->GetAudioOutSamples( synth->buffersize, synth->samplerate, outputl.data(), outputr.data() ); // TODO: move to MixHelpers for( int f = 0; f < synth->buffersize; ++f ) diff --git a/plugins/zynaddsubfx/RemoteZynAddSubFx.cpp b/plugins/zynaddsubfx/RemoteZynAddSubFx.cpp index 7cb6e635a8b..cdf68571ac0 100644 --- a/plugins/zynaddsubfx/RemoteZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/RemoteZynAddSubFx.cpp @@ -28,6 +28,8 @@ #endif #include +#include +#include #define BUILD_REMOTE_PLUGIN_CLIENT #include "Note.h" @@ -61,8 +63,7 @@ class RemoteZynAddSubFx : public RemotePluginClient, public LocalZynAddSubFx sendMessage( IdInitDone ); waitForMessage( IdInitDone ); - pthread_mutex_init( &m_guiMutex, NULL ); - pthread_create( &m_messageThreadHandle, NULL, messageLoop, this ); + m_messageThread = std::thread(&RemoteZynAddSubFx::messageLoop, this); } virtual ~RemoteZynAddSubFx() @@ -85,9 +86,9 @@ class RemoteZynAddSubFx : public RemotePluginClient, public LocalZynAddSubFx message m; while( ( m = receiveMessage() ).id != IdQuit ) { - pthread_mutex_lock( &m_master->mutex ); + m_master->mutex.lock(); processMessage( m ); - pthread_mutex_unlock( &m_master->mutex ); + m_master->mutex.unlock(); } m_guiExit = true; } @@ -103,9 +104,9 @@ class RemoteZynAddSubFx : public RemotePluginClient, public LocalZynAddSubFx case IdHideUI: case IdLoadSettingsFromFile: case IdLoadPresetFile: - pthread_mutex_lock( &m_guiMutex ); + m_guiMutex.lock(); m_guiMessages.push( _m ); - pthread_mutex_unlock( &m_guiMutex ); + m_guiMutex.unlock(); break; case IdSaveSettingsToFile: @@ -145,23 +146,13 @@ class RemoteZynAddSubFx : public RemotePluginClient, public LocalZynAddSubFx LocalZynAddSubFx::processAudio( _out ); } - static void * messageLoop( void * _arg ) - { - RemoteZynAddSubFx * _this = - static_cast( _arg ); - - _this->messageLoop(); - - return NULL; - } - 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 m_guiMessages; bool m_guiExit; @@ -191,12 +182,12 @@ void RemoteZynAddSubFx::guiLoop() } if( exitProgram == 1 ) { - pthread_mutex_lock( &m_master->mutex ); + m_master->mutex.lock(); sendMessage( IdHideUI ); exitProgram = 0; - pthread_mutex_unlock( &m_master->mutex ); + m_master->mutex.unlock(); } - pthread_mutex_lock( &m_guiMutex ); + m_guiMutex.lock(); while( m_guiMessages.size() ) { RemotePluginClient::message m = m_guiMessages.front(); @@ -221,9 +212,9 @@ void RemoteZynAddSubFx::guiLoop() { ui->refresh_master_ui(); } - pthread_mutex_lock( &m_master->mutex ); + m_master->mutex.lock(); sendMessage( IdLoadSettingsFromFile ); - pthread_mutex_unlock( &m_master->mutex ); + m_master->mutex.unlock(); break; } @@ -237,9 +228,9 @@ void RemoteZynAddSubFx::guiLoop() ui->updatepanel(); ui->refresh_master_ui(); } - pthread_mutex_lock( &m_master->mutex ); + m_master->mutex.lock(); sendMessage( IdLoadPresetFile ); - pthread_mutex_unlock( &m_master->mutex ); + m_master->mutex.unlock(); break; } @@ -247,7 +238,7 @@ void RemoteZynAddSubFx::guiLoop() break; } } - pthread_mutex_unlock( &m_guiMutex ); + m_guiMutex.unlock(); } Fl::flush(); @@ -269,7 +260,7 @@ int main( int _argc, char * * _argv ) return -1; } -#ifdef LMMS_BUILD_WIN32 +#if defined(LMMS_BUILD_WIN32) && !defined(_MSC_VER) #ifndef __WINPTHREADS_VERSION // (non-portable) initialization of statically linked pthread library pthread_win32_process_attach_np(); @@ -290,7 +281,7 @@ int main( int _argc, char * * _argv ) delete remoteZASF; -#ifdef LMMS_BUILD_WIN32 +#if defined(LMMS_BUILD_WIN32) && !defined(_MSC_VER) #ifndef __WINPTHREADS_VERSION pthread_win32_thread_detach_np(); pthread_win32_process_detach_np(); diff --git a/plugins/zynaddsubfx/zynaddsubfx b/plugins/zynaddsubfx/zynaddsubfx index 9cd29e22432..7c837b433f3 160000 --- a/plugins/zynaddsubfx/zynaddsubfx +++ b/plugins/zynaddsubfx/zynaddsubfx @@ -1 +1 @@ -Subproject commit 9cd29e224320c40b00343b7e49e586ef25733a71 +Subproject commit 7c837b433f3e46d99c589808f39c43b17976eec1 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fa9754005b2..7326e0b354a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -51,12 +51,13 @@ ADD_GEN_QRC(LMMS_RCC_OUT lmms.qrc # Paths relative to lmms executable FILE(RELATIVE_PATH LIB_DIR_RELATIVE "/${BIN_DIR}" "/${LIB_DIR}") FILE(RELATIVE_PATH PLUGIN_DIR_RELATIVE "/${BIN_DIR}" "/${PLUGIN_DIR}") -ADD_DEFINITIONS(-D'LIB_DIR="${LIB_DIR_RELATIVE}/"' -D'PLUGIN_DIR="${PLUGIN_DIR_RELATIVE}/"' ${PULSEAUDIO_DEFINITIONS} ${PORTAUDIO_DEFINITIONS}) +ADD_DEFINITIONS(-DLIB_DIR="${LIB_DIR_RELATIVE}" -DPLUGIN_DIR="${PLUGIN_DIR_RELATIVE}" ${PULSEAUDIO_DEFINITIONS} ${PORTAUDIO_DEFINITIONS}) INCLUDE_DIRECTORIES( ${JACK_INCLUDE_DIRS} ${SAMPLERATE_INCLUDE_DIRS} ${SNDFILE_INCLUDE_DIRS} ${SNDIO_INCLUDE_DIRS} + ${FFTW3F_INCLUDE_DIRS} ) IF(NOT ("${SDL2_INCLUDE_DIR}" STREQUAL "")) @@ -111,6 +112,10 @@ ADD_EXECUTABLE(lmms $ "${WINRC}" ) +IF(MSVC) + SET_PROPERTY(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT lmms) +ENDIF(MSVC) + TARGET_INCLUDE_DIRECTORIES(lmms PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ) @@ -183,89 +188,204 @@ IF(LMMS_BUILD_MSYS AND CMAKE_BUILD_TYPE STREQUAL "Debug") ENDIF() # Install -IF(LMMS_BUILD_WIN32) - SET_TARGET_PROPERTIES(lmms PROPERTIES - LINK_FLAGS "${LINK_FLAGS} -mwindows" - ENABLE_EXPORTS ON - ) - IF(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - ADD_CUSTOM_COMMAND(TARGET lmms POST_BUILD COMMAND "${STRIP}" "$") - ENDIF() +IF(NOT MSVC) + IF(LMMS_BUILD_WIN32) + SET_TARGET_PROPERTIES(lmms PROPERTIES + LINK_FLAGS "${LINK_FLAGS} -mwindows" + ENABLE_EXPORTS ON + ) + IF(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + ADD_CUSTOM_COMMAND(TARGET lmms POST_BUILD COMMAND "${STRIP}" "$") + ENDIF() - INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") - - INSTALL(FILES - "${MINGW_PREFIX}/bin/Qt5Core.dll" - "${MINGW_PREFIX}/bin/Qt5Gui.dll" - "${MINGW_PREFIX}/bin/Qt5Widgets.dll" - "${MINGW_PREFIX}/bin/Qt5Xml.dll" - DESTINATION .) - INSTALL(FILES - "${MINGW_PREFIX}/lib/qt5/plugins/platforms/qwindows.dll" - DESTINATION ./platforms) - INSTALL(FILES - "${MINGW_PREFIX}/bin/libsamplerate-0.dll" - "${MINGW_PREFIX}/bin/libsndfile-1.dll" - "${MINGW_PREFIX}/bin/libvorbis-0.dll" - "${MINGW_PREFIX}/bin/libvorbisenc-2.dll" - "${MINGW_PREFIX}/bin/libvorbisfile-3.dll" - "${MINGW_PREFIX}/bin/libjpeg-9.dll" - "${MINGW_PREFIX}/bin/libogg-0.dll" - "${MINGW_PREFIX}/bin/libmp3lame-0.dll" - "${MINGW_PREFIX}/bin/libfftw3f-3.dll" - "${MINGW_PREFIX}/bin/libFLAC-8.dll" - "${MINGW_PREFIX}/bin/libpng16-16.dll" - "${MINGW_PREFIX}/bin/SDL.dll" - "${MINGW_PREFIX}/bin/libglib-2.0-0.dll" - "${MINGW_PREFIX}/bin/libgthread-2.0-0.dll" - "${MINGW_PREFIX}/bin/zlib1.dll" - "${MINGW_PREFIX}/${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32/bin/libwinpthread-1.dll" - DESTINATION .) - IF(LMMS_BUILD_MSYS) + INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") INSTALL(FILES - "${MINGW_PREFIX}/bin/libwinpthread-1.dll" - "${MINGW_PREFIX}/bin/libgcc_s_seh-1.dll" - "${MINGW_PREFIX}/bin/libstdc++-6.dll" + "${MINGW_PREFIX}/bin/Qt5Core.dll" + "${MINGW_PREFIX}/bin/Qt5Gui.dll" + "${MINGW_PREFIX}/bin/Qt5Widgets.dll" + "${MINGW_PREFIX}/bin/Qt5Xml.dll" DESTINATION .) - ELSE() INSTALL(FILES - "${MINGW_PREFIX}/${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32/bin/libwinpthread-1.dll" - DESTINATION .) - ENDIF() - IF(FLTK_FOUND) + "${MINGW_PREFIX}/lib/qt5/plugins/platforms/qwindows.dll" + DESTINATION ./platforms) INSTALL(FILES - "${MINGW_PREFIX}/bin/libfltk.dll" - DESTINATION .) - ENDIF() - IF(FLUIDSYNTH_FOUND) + "${MINGW_PREFIX}/bin/libsamplerate-0.dll" + "${MINGW_PREFIX}/bin/libsndfile-1.dll" + "${MINGW_PREFIX}/bin/libvorbis-0.dll" + "${MINGW_PREFIX}/bin/libvorbisenc-2.dll" + "${MINGW_PREFIX}/bin/libvorbisfile-3.dll" + "${MINGW_PREFIX}/bin/libjpeg-9.dll" + "${MINGW_PREFIX}/bin/libogg-0.dll" + "${MINGW_PREFIX}/bin/libmp3lame-0.dll" + "${MINGW_PREFIX}/bin/libfftw3f-3.dll" + "${MINGW_PREFIX}/bin/libFLAC-8.dll" + "${MINGW_PREFIX}/bin/libpng16-16.dll" + "${MINGW_PREFIX}/bin/SDL.dll" + "${MINGW_PREFIX}/bin/libglib-2.0-0.dll" + "${MINGW_PREFIX}/bin/libgthread-2.0-0.dll" + "${MINGW_PREFIX}/bin/zlib1.dll" + "${MINGW_PREFIX}/${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32/bin/libwinpthread-1.dll" + DESTINATION .) + IF(LMMS_BUILD_MSYS) + INSTALL(FILES + "${MINGW_PREFIX}/bin/libwinpthread-1.dll" + "${MINGW_PREFIX}/bin/libgcc_s_seh-1.dll" + "${MINGW_PREFIX}/bin/libstdc++-6.dll" + DESTINATION .) + ELSE() + INSTALL(FILES + "${MINGW_PREFIX}/${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32/bin/libwinpthread-1.dll" + DESTINATION .) + ENDIF() + IF(FLTK_FOUND) + INSTALL(FILES + "${MINGW_PREFIX}/bin/libfltk.dll" + DESTINATION .) + ENDIF() + IF(FLUIDSYNTH_FOUND) + INSTALL(FILES + "${MINGW_PREFIX}/bin/libfluidsynth.dll" + DESTINATION .) + ENDIF() + IF(GIG_FOUND) + # Handle libgig-*.dll + FILE(GLOB GIG_LIBRARY "${MINGW_PREFIX}/bin/libgig-*.dll") + INSTALL(FILES + ${GIG_LIBRARY} + DESTINATION .) + ENDIF() + IF(PORTAUDIO_FOUND) + INSTALL(FILES + "${MINGW_PREFIX}/bin/libportaudio-2.dll" + DESTINATION .) + ENDIF() + IF(SOUNDIO_FOUND) + INSTALL(FILES + "${MINGW_PREFIX}/lib/libsoundio.dll" + DESTINATION .) + ENDIF() + + ELSE(LMMS_BUILD_WIN32) + IF(NOT LMMS_BUILD_APPLE) + SET_TARGET_PROPERTIES(lmms PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Wl,-E") + ENDIF(NOT LMMS_BUILD_APPLE) + + INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") + INSTALL(FILES "${CMAKE_BINARY_DIR}/lmms.1.gz" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/man/man1/" PERMISSIONS OWNER_READ GROUP_READ WORLD_READ) + + ENDIF(LMMS_BUILD_WIN32) +ELSE(NOT MSVC) + SET_TARGET_PROPERTIES(lmms PROPERTIES + ENABLE_EXPORTS ON + ) + INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") + + SET_TARGET_PROPERTIES(lmms PROPERTIES + LINK_FLAGS "${LINK_FLAGS} -mwindows" + ENABLE_EXPORTS ON + ) + + #CMAKE_FIND_ROOT_PATH + SET(VCPKG_ROOT ${CMAKE_FIND_ROOT_PATH}) + + INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") + INSTALL(FILES - "${MINGW_PREFIX}/bin/libfluidsynth.dll" + "${VCPKG_ROOT}/bin/Qt5Core.dll" + "${VCPKG_ROOT}/bin/Qt5Gui.dll" + "${VCPKG_ROOT}/bin/Qt5Widgets.dll" + "${VCPKG_ROOT}/bin/Qt5Xml.dll" + + "${VCPKG_ROOT}/bin/zlib1.dll" + "${VCPKG_ROOT}/bin/jpeg62.dll" + "${VCPKG_ROOT}/bin/libpng16.dll" + "${VCPKG_ROOT}/bin/gthread-2.dll" + "${VCPKG_ROOT}/bin/glib-2.dll" + "${VCPKG_ROOT}/bin/harfbuzz.dll" + "${VCPKG_ROOT}/bin/pcre2-16.dll" + "${VCPKG_ROOT}/bin/double-conversion.dll" + "${VCPKG_ROOT}/bin/freetype.dll" + "${VCPKG_ROOT}/bin/libbz2.dll" + "${VCPKG_ROOT}/bin/pcre.dll" + "${VCPKG_ROOT}/bin/libiconv.dll" + "${VCPKG_ROOT}/bin/libcharset.dll" + "${VCPKG_ROOT}/bin/libintl.dll" DESTINATION .) - ENDIF() - IF(GIG_FOUND) - # Handle libgig-*.dll - FILE(GLOB GIG_LIBRARY "${MINGW_PREFIX}/bin/libgig-*.dll") + INSTALL(FILES - ${GIG_LIBRARY} - DESTINATION .) - ENDIF() - IF(PORTAUDIO_FOUND) + "${VCPKG_ROOT}/plugins/platforms/qwindows.dll" + DESTINATION ./platforms) + INSTALL(FILES - "${MINGW_PREFIX}/bin/libportaudio-2.dll" + "${VCPKG_ROOT}/bin/libsndfile-1.dll" + "${VCPKG_ROOT}/bin/ogg.dll" + "${VCPKG_ROOT}/bin/vorbis.dll" + "${VCPKG_ROOT}/bin/vorbisenc.dll" + "${VCPKG_ROOT}/bin/FLAC.dll" + "${VCPKG_ROOT}/bin/vorbisfile.dll" + + "${VCPKG_ROOT}/bin/libsamplerate-0.dll" + "${VCPKG_ROOT}/bin/SDL2.dll" + "${VCPKG_ROOT}/bin/fftw3f.dll" DESTINATION .) - ENDIF() - IF(SOUNDIO_FOUND) - INSTALL(FILES - "${MINGW_PREFIX}/lib/libsoundio.dll" + + #not yet in vcpkg + #IF(LAME_FOUND) + # INSTALL(FILES + # "${VCPKG_ROOT}/bin/libmp3lame-0.dll" + # DESTINATION .) + #ENDIF(LAME_FOUND) + + IF(FLTK_FOUND) + INSTALL(FILES + "${VCPKG_ROOT}/bin/libfltk_SHARED.dll" + + "${VCPKG_ROOT}/bin/zlib1.dll" + "${VCPKG_ROOT}/bin/jpeg62.dll" DESTINATION .) - ENDIF() - -ELSE(LMMS_BUILD_WIN32) - IF(NOT LMMS_BUILD_APPLE) - SET_TARGET_PROPERTIES(lmms PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Wl,-E") - ENDIF(NOT LMMS_BUILD_APPLE) - - INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") - INSTALL(FILES "${CMAKE_BINARY_DIR}/lmms.1.gz" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/man/man1/" PERMISSIONS OWNER_READ GROUP_READ WORLD_READ) + ENDIF() + + IF(FLUIDSYNTH_FOUND) + INSTALL(FILES + "${VCPKG_ROOT}/bin/libfluidsynth-1.dll" + "${VCPKG_ROOT}/bin/glib-2.dll" + "${VCPKG_ROOT}/bin/pcre.dll" + "${VCPKG_ROOT}/bin/libiconv.dll" + "${VCPKG_ROOT}/bin/libcharset.dll" + "${VCPKG_ROOT}/bin/libintl.dll" + DESTINATION .) + ENDIF() -ENDIF(LMMS_BUILD_WIN32) + #not yet included in vcpkg + #IF(GIG_FOUND) + # # Handle libgig-*.dll + # FILE(GLOB GIG_LIBRARY "${VCPKG_ROOT}/bin/libgig-*.dll") + # INSTALL(FILES + # ${GIG_LIBRARY} + # DESTINATION .) + #ENDIF() + + IF(PORTAUDIO_FOUND) + IF(LMMS_BUILD_WIN64) + INSTALL(FILES + "${VCPKG_ROOT}/bin/portaudio_x64.dll" + DESTINATION .) + ELSE(LMMS_BUILD_WIN64) + INSTALL(FILES + "${VCPKG_ROOT}/bin/portaudio_x86.dll" + DESTINATION .) + ENDIF(LMMS_BUILD_WIN64) + ENDIF() + + #TODO: quick hack to make an installer + IF(JACK_FOUND) + INSTALL(FILES ${JACK_LIBRARY_DLL} DESTINATION .) + ENDIF(JACK_FOUND) + + #not yet in vcpkg + #IF(SOUNDIO_FOUND) + # INSTALL(FILES + # "${VCPKG_ROOT}/bin/libsoundio.dll" + # DESTINATION .) + #ENDIF() +ENDIF(NOT MSVC) \ No newline at end of file diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index 35ffa73cc04..93101141d6d 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -186,8 +186,8 @@ Mixer::~Mixer() } delete m_fifo; - delete m_audioDev; delete m_midiClient; + delete m_audioDev; for( int i = 0; i < 3; i++ ) { diff --git a/src/core/RemotePlugin.cpp b/src/core/RemotePlugin.cpp index c5b8f05b6c8..491dfeac146 100644 --- a/src/core/RemotePlugin.cpp +++ b/src/core/RemotePlugin.cpp @@ -55,7 +55,7 @@ ProcessWatcher::ProcessWatcher( RemotePlugin * _p ) : void ProcessWatcher::run() { - while( !m_quit && m_plugin->isRunning() ) + while( !m_quit && (m_plugin->messagesLeft() || m_plugin->isRunning()) ) { msleep( 200 ); } diff --git a/src/core/audio/AudioJack.cpp b/src/core/audio/AudioJack.cpp index 4d730eed412..50f39d738fc 100644 --- a/src/core/audio/AudioJack.cpp +++ b/src/core/audio/AudioJack.cpp @@ -50,7 +50,6 @@ AudioJack::AudioJack( bool & _success_ful, Mixer* _mixer ) : _mixer ), m_client( NULL ), m_active( false ), - m_midiClient( NULL ), m_tempOutBufs( new jack_default_audio_sample_t *[channels()] ), m_outBuf( new surroundSampleFrame[mixer()->framesPerPeriod()] ), m_framesDoneInCurBuf( 0 ), @@ -79,13 +78,14 @@ AudioJack::~AudioJack() } #endif - if( m_client != NULL ) + if( m_client != nullptr ) { if( m_active ) { jack_deactivate( m_client ); } jack_client_close( m_client ); + m_client = nullptr; } delete[] m_tempOutBufs; @@ -123,15 +123,6 @@ void AudioJack::restartAfterZombified() -AudioJack* AudioJack::addMidiClient(MidiJack *midiClient) -{ - if( m_client == NULL ) - return NULL; - - m_midiClient = midiClient; - - return this; -} bool AudioJack::initJackClient() { @@ -245,8 +236,10 @@ void AudioJack::startProcessing() } } } - - free( ports ); + //HACK: + //TODO: Very important, don't commit to lmms master + //I need to find out how to properly deallocate this + //free( ports ); } @@ -344,14 +337,6 @@ int AudioJack::processCallback( jack_nframes_t _nframes, void * _udata ) { QMutexLocker m( &m_processingMutex ); - // do midi processing first so that midi input can - // add to the following sound processing - if( m_midiClient && _nframes > 0 ) - { - m_midiClient->JackMidiRead(_nframes); - m_midiClient->JackMidiWrite(_nframes); - } - for( int c = 0; c < channels(); ++c ) { m_tempOutBufs[c] = diff --git a/src/core/audio/AudioSdl.cpp b/src/core/audio/AudioSdl.cpp index 2b810e91374..8d91aebf38a 100644 --- a/src/core/audio/AudioSdl.cpp +++ b/src/core/audio/AudioSdl.cpp @@ -1,26 +1,26 @@ /* - * AudioSdl.cpp - device-class that performs PCM-output via SDL - * - * Copyright (c) 2004-2009 Tobias Doerffel - * - * This file is part of LMMS - https://lmms.io - * - * 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. - * - */ +* AudioSdl.cpp - device-class that performs PCM-output via SDL +* +* Copyright (c) 2004-2009 Tobias Doerffel +* +* This file is part of LMMS - https://lmms.io +* +* 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. +* +*/ #include "AudioSdl.h" @@ -34,47 +34,89 @@ #include "gui_templates.h" #include "Mixer.h" - -AudioSdl::AudioSdl( bool & _success_ful, Mixer* _mixer ) : - AudioDevice( DEFAULT_CHANNELS, _mixer ), - m_outBuf( new surroundSampleFrame[mixer()->framesPerPeriod()] ), - m_convertedBufPos( 0 ), - m_convertEndian( false ) +AudioSdl::AudioSdl(bool & _success_ful, Mixer* _mixer) : + AudioDevice(DEFAULT_CHANNELS, _mixer), + m_outBuf(new surroundSampleFrame[mixer()->framesPerPeriod()]) { _success_ful = false; +#ifdef LMMS_HAVE_SDL2 + m_currentBufferFramesCount = 0; + m_currentBufferFramePos = 0; +#else m_convertedBufSize = mixer()->framesPerPeriod() * channels() - * sizeof( int_sample_t ); + * sizeof(int_sample_t); + m_convertedBufPos = 0; m_convertedBuf = new Uint8[m_convertedBufSize]; +#endif - - if( SDL_Init( SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE ) < 0 ) + if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE) < 0) { - qCritical( "Couldn't initialize SDL: %s\n", SDL_GetError() ); + qCritical("Couldn't initialize SDL: %s\n", SDL_GetError()); return; } m_audioHandle.freq = sampleRate(); +#ifdef LMMS_HAVE_SDL2 + m_audioHandle.format = AUDIO_F32SYS; // we want it in byte-order + // of system, so we don't have + // to convert the buffers +#else m_audioHandle.format = AUDIO_S16SYS; // we want it in byte-order - // of system, so we don't have - // to convert the buffers + // of system, so we don't have + // to convert the buffers +#endif m_audioHandle.channels = channels(); - m_audioHandle.samples = qMax( 1024, mixer()->framesPerPeriod()*2 ); + m_audioHandle.samples = qMax(1024, mixer()->framesPerPeriod() * 2); m_audioHandle.callback = sdlAudioCallback; m_audioHandle.userdata = this; - SDL_AudioSpec actual; + SDL_AudioSpec actual; +#ifdef LMMS_HAVE_SDL2 + m_outputDevice = SDL_OpenAudioDevice(NULL, + 0, + &m_audioHandle, + &actual, + 0); + if (m_outputDevice == 0) { + qCritical("Couldn't open SDL-audio: %s\n", SDL_GetError()); + return; + } +#else // open the audio device, forcing the desired format - if( SDL_OpenAudio( &m_audioHandle, &actual ) < 0 ) + if (SDL_OpenAudio(&m_audioHandle, &actual) < 0) { - qCritical( "Couldn't open SDL-audio: %s\n", SDL_GetError() ); + qCritical("Couldn't open SDL-audio: %s\n", SDL_GetError()); return; } - m_convertEndian = ( m_audioHandle.format != actual.format ); + + m_outConvertEndian = (m_audioHandle.format != actual.format); +#endif + _success_ful = true; + +#ifdef LMMS_HAVE_SDL2 + m_inputAudioHandle = m_audioHandle; + m_inputAudioHandle.freq = mixer()->inputSampleRate(); + m_inputAudioHandle.callback = sdlInputAudioCallback; + + m_inputDevice = SDL_OpenAudioDevice(NULL, + 1, + &m_inputAudioHandle, + &actual, + 0); + if (m_inputDevice != 0 && actual.freq == mixer()->inputSampleRate()) { + m_supportsCapture = true; + } + else { + m_supportsCapture = false; + qWarning("Couldn't open SDL capture device: %s\n", SDL_GetError()); + } + +#endif } @@ -84,9 +126,18 @@ AudioSdl::~AudioSdl() { stopProcessing(); +#ifdef LMMS_HAVE_SDL2 + if (m_inputDevice != 0) + SDL_CloseAudioDevice(m_inputDevice); + if (m_outputDevice != 0) + SDL_CloseAudioDevice(m_outputDevice); +#else SDL_CloseAudio(); - SDL_Quit(); delete[] m_convertedBuf; +#endif + + SDL_Quit(); + delete[] m_outBuf; } @@ -97,7 +148,12 @@ void AudioSdl::startProcessing() { m_stopped = false; - SDL_PauseAudio( 0 ); +#ifdef LMMS_HAVE_SDL2 + SDL_PauseAudioDevice(m_outputDevice, 0); + SDL_PauseAudioDevice(m_inputDevice, 0); +#else + SDL_PauseAudio(0); +#endif } @@ -105,12 +161,30 @@ void AudioSdl::startProcessing() void AudioSdl::stopProcessing() { - if( SDL_GetAudioStatus() == SDL_AUDIO_PLAYING ) +#ifdef LMMS_HAVE_SDL2 + if (SDL_GetAudioDeviceStatus(m_outputDevice) == SDL_AUDIO_PLAYING) +#else + if (SDL_GetAudioStatus() == SDL_AUDIO_PLAYING) +#endif { +#ifdef LMMS_HAVE_SDL2 + SDL_LockAudioDevice(m_inputDevice); + SDL_LockAudioDevice(m_outputDevice); + + m_stopped = true; + + SDL_PauseAudioDevice(m_inputDevice, 1); + SDL_PauseAudioDevice(m_outputDevice, 1); + + SDL_UnlockAudioDevice(m_inputDevice); + SDL_UnlockAudioDevice(m_outputDevice); +#else SDL_LockAudio(); m_stopped = true; - SDL_PauseAudio( 1 ); + SDL_PauseAudio(1); SDL_UnlockAudio(); +#endif + } } @@ -119,22 +193,25 @@ void AudioSdl::stopProcessing() void AudioSdl::applyQualitySettings() { - if( 0 )//hqAudio() ) + // Better than if (0) +#if 0 + if (0)//hqAudio() ) { SDL_CloseAudio(); - setSampleRate( Engine::mixer()->processingSampleRate() ); + setSampleRate(Engine::mixer()->processingSampleRate()); m_audioHandle.freq = sampleRate(); - SDL_AudioSpec actual; + SDL_AudioSpec actual; // open the audio device, forcing the desired format - if( SDL_OpenAudio( &m_audioHandle, &actual ) < 0 ) + if (SDL_OpenAudio(&m_audioHandle, &actual) < 0) { - qCritical( "Couldn't open SDL-audio: %s\n", SDL_GetError() ); + qCritical("Couldn't open SDL-audio: %s\n", SDL_GetError()); } } +#endif AudioDevice::applyQualitySettings(); } @@ -142,66 +219,116 @@ void AudioSdl::applyQualitySettings() -void AudioSdl::sdlAudioCallback( void * _udata, Uint8 * _buf, int _len ) +void AudioSdl::sdlAudioCallback(void * _udata, Uint8 * _buf, int _len) { - AudioSdl * _this = static_cast( _udata ); + AudioSdl * _this = static_cast(_udata); - _this->sdlAudioCallback( _buf, _len ); + _this->sdlAudioCallback(_buf, _len); } -void AudioSdl::sdlAudioCallback( Uint8 * _buf, int _len ) +void AudioSdl::sdlAudioCallback(Uint8 * _buf, int _len) { - if( m_stopped ) + if (m_stopped) { - memset( _buf, 0, _len ); + memset(_buf, 0, _len); return; } - while( _len ) + // SDL2: process float samples +#ifdef LMMS_HAVE_SDL2 + while (_len) + { + if (m_currentBufferFramePos == 0) + { + // frames depend on the sample rate + const fpp_t frames = getNextBuffer(m_outBuf); + if (!frames) + { + memset(_buf, 0, _len); + return; + } + m_currentBufferFramesCount = frames; + + } + const uint min_frames_count = qMin(_len / sizeof(sampleFrame), + m_currentBufferFramesCount + - m_currentBufferFramePos); + + const float gain = mixer()->masterGain(); + for (uint f = 0; f < min_frames_count; f++) + { + (m_outBuf + m_currentBufferFramePos)[f][0] *= gain; + (m_outBuf + m_currentBufferFramePos)[f][1] *= gain; + } + + memcpy(_buf, m_outBuf + m_currentBufferFramePos, min_frames_count * sizeof(sampleFrame)); + _buf += min_frames_count * sizeof(sampleFrame); + _len -= min_frames_count * sizeof(sampleFrame); + m_currentBufferFramePos += min_frames_count; + + m_currentBufferFramePos %= m_currentBufferFramesCount; + } +#else + while (_len) { - if( m_convertedBufPos == 0 ) + if (m_convertedBufPos == 0) { // frames depend on the sample rate - const fpp_t frames = getNextBuffer( m_outBuf ); - if( !frames ) + const fpp_t frames = getNextBuffer(m_outBuf); + if (!frames) { - memset( _buf, 0, _len ); + memset(_buf, 0, _len); return; } m_convertedBufSize = frames * channels() - * sizeof( int_sample_t ); + * sizeof(int_sample_t); - convertToS16( m_outBuf, frames, - mixer()->masterGain(), - (int_sample_t *)m_convertedBuf, - m_convertEndian ); + convertToS16(m_outBuf, frames, + mixer()->masterGain(), + (int_sample_t *)m_convertedBuf, + m_outConvertEndian); } - const int min_len = qMin( _len, m_convertedBufSize - - m_convertedBufPos ); - memcpy( _buf, m_convertedBuf + m_convertedBufPos, min_len ); + const int min_len = qMin(_len, m_convertedBufSize + - m_convertedBufPos); + memcpy(_buf, m_convertedBuf + m_convertedBufPos, min_len); _buf += min_len; _len -= min_len; m_convertedBufPos += min_len; m_convertedBufPos %= m_convertedBufSize; } +#endif } +#ifdef LMMS_HAVE_SDL2 +void AudioSdl::sdlInputAudioCallback(void *_udata, Uint8 *_buf, int _len) { + AudioSdl * _this = static_cast(_udata); + _this->sdlInputAudioCallback(_buf, _len); +} + +void AudioSdl::sdlInputAudioCallback(Uint8 *_buf, int _len) { + sampleFrame *samples_buffer = (sampleFrame *)_buf; + fpp_t frames = _len / sizeof(sampleFrame); + + mixer()->pushInputFrames(samples_buffer, frames); +} + +#endif -AudioSdl::setupWidget::setupWidget( QWidget * _parent ) : - AudioDeviceSetupWidget( AudioSdl::name(), _parent ) +AudioSdl::setupWidget::setupWidget(QWidget * _parent) : + AudioDeviceSetupWidget(AudioSdl::name(), _parent) { - QString dev = ConfigManager::inst()->value( "audiosdl", "device" ); - m_device = new QLineEdit( dev, this ); - m_device->setGeometry( 10, 20, 160, 20 ); + QString dev = ConfigManager::inst()->value("audiosdl", "device"); + m_device = new QLineEdit(dev, this); + m_device->setGeometry(10, 20, 160, 20); - QLabel * dev_lbl = new QLabel( tr( "DEVICE" ), this ); - dev_lbl->setFont( pointSize<7>( dev_lbl->font() ) ); - dev_lbl->setGeometry( 10, 40, 160, 10 ); + QLabel * dev_lbl = new QLabel(tr("DEVICE"), this); + dev_lbl->setFont(pointSize<7>(dev_lbl->font())); + dev_lbl->setGeometry(10, 40, 160, 10); } @@ -217,8 +344,8 @@ AudioSdl::setupWidget::~setupWidget() void AudioSdl::setupWidget::saveSettings() { - ConfigManager::inst()->setValue( "audiosdl", "device", - m_device->text() ); + ConfigManager::inst()->setValue("audiosdl", "device", + m_device->text()); } diff --git a/src/core/midi/MidiJack.cpp b/src/core/midi/MidiJack.cpp index cea7f7381e7..e46267f8d2f 100644 --- a/src/core/midi/MidiJack.cpp +++ b/src/core/midi/MidiJack.cpp @@ -65,39 +65,26 @@ MidiJack::MidiJack() : m_output_port( NULL ), m_quit( false ) { - // if jack is currently used for audio then we share the connection - // AudioJack creates and maintains the jack connection - // and also handles the callback, we pass it our address - // so that we can also process during the callback + m_jackClient = jack_client_open(probeDevice().toLatin1().data(), + JackNoStartServer, NULL); - m_jackAudio = dynamic_cast(Engine::mixer()->audioDev()); - if( m_jackAudio ) + if(m_jackClient) { - // if a jack connection has been created for audio we use that - m_jackAudio->addMidiClient(this); - }else{ - m_jackAudio = NULL; - m_jackClient = jack_client_open(probeDevice().toLatin1().data(), - JackNoStartServer, NULL); - - if(m_jackClient) - { - jack_set_process_callback(m_jackClient, - JackMidiProcessCallback, this); - jack_on_shutdown(m_jackClient, - JackMidiShutdown, 0); - } + jack_set_process_callback(m_jackClient, + JackMidiProcessCallback, this); + jack_on_shutdown(m_jackClient, + JackMidiShutdown, 0); } if(jackClient()) { /* jack midi out not implemented JackMidiWrite and sendByte needs to be functional - before enabling this + before enabling this*/ m_output_port = jack_port_register( jackClient(), "MIDI out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); - */ + m_input_port = jack_port_register( jackClient(), "MIDI in", JACK_DEFAULT_MIDI_TYPE, @@ -145,13 +132,7 @@ MidiJack::~MidiJack() jack_client_t* MidiJack::jackClient() { - if( m_jackAudio == NULL && m_jackClient == NULL) - return NULL; - - if( m_jackAudio == NULL && m_jackClient ) - return m_jackClient; - - return m_jackAudio->jackClient(); + return m_jackClient; } QString MidiJack::probeDevice() @@ -197,13 +178,28 @@ void MidiJack::JackMidiRead(jack_nframes_t nframes) void MidiJack::sendByte( const unsigned char c ) { - //m_midiDev.putChar( c ); + std::lock_guard lock(m_bufferLock); + m_midibuffer.push_back(c); } // we write data to jack void MidiJack::JackMidiWrite(jack_nframes_t nframes) { - // TODO: write midi data to jack port + { + std::lock_guard lock(m_bufferLock); + if (!m_midibuffer.empty()) + { + void* portBuffer = jack_port_get_buffer(m_output_port, nframes); + jack_midi_clear_buffer(portBuffer); + void* buffer = jack_midi_event_reserve(portBuffer, 0, m_midibuffer.size()); + if (buffer) + { + memcpy(buffer, m_midibuffer.data(), m_midibuffer.size()); + } + m_midibuffer.clear(); + } + } + } void MidiJack::run() diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index f88e1dcf6ce..76e29fee301 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -839,8 +839,18 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : ConfigManager::inst()->setValue( "mixer", "audiodev", audioDevName ); } - m_audioInterfaces-> - setCurrentIndex( m_audioInterfaces->findText( audioDevName ) ); + + int index = m_audioInterfaces->findText(audioDevName); + //check index, during debugging (dis/en)abling audio devices this can cause a crash (index -1) + //TODO: output error msg? + if (index < 0) + { + audioDevName = Engine::mixer()->audioDevName(); + ConfigManager::inst()->setValue( + "mixer", "audiodev", audioDevName); + } + + m_audioInterfaces->setCurrentIndex(m_audioInterfaces->findText(audioDevName)); m_audioIfaceSetupWidgets[audioDevName]->show(); connect( m_audioInterfaces, SIGNAL( activated( const QString & ) ), @@ -942,8 +952,18 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : ConfigManager::inst()->setValue( "mixer", "mididev", midiDevName ); } - m_midiInterfaces->setCurrentIndex( - m_midiInterfaces->findText( midiDevName ) ); + + index = m_midiInterfaces->findText(midiDevName); + //not found? init to default + //TODO: output error msg? + if (index < 0) + { + midiDevName = Engine::mixer()->midiClientName(); + ConfigManager::inst()->setValue( + "mixer", "mididev", midiDevName); + } + + m_midiInterfaces->setCurrentIndex(m_midiInterfaces->findText(midiDevName)); m_midiIfaceSetupWidgets[midiDevName]->show(); connect( m_midiInterfaces, SIGNAL( activated( const QString & ) ),