# To get started on a new plugin, copy this entire folder (containing this file and C++ sources) to # a convenient location, and then start making modifications. # The first line of any CMake project should be a call to `cmake_minimum_required`, which checks # that the installed CMake will be able to understand the following CMakeLists, and ensures that # CMake's behaviour is compatible with the named version. This is a standard CMake command, so more # information can be found in the CMake docs. cmake_minimum_required(VERSION 3.15) set (CMAKE_CXX_STANDARD 20) if (WIN32) #set (CMAKE_GENERATOR_TOOLSET ClangCL) #static linking in Windows set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") endif() # If we are compiling for Mac OS we want to target OS versions down to 10.9 option(UniversalBinary "Build universal binary for mac" ON) if (APPLE) set (CMAKE_OSX_DEPLOYMENT_TARGET "10.10" CACHE INTERNAL "") if (UniversalBinary) set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE INTERNAL "") #set(CMAKE_OSX_ARCHITECTURES arm64 x86_64) endif() endif() # The top-level CMakeLists.txt file for a project must contain a literal, direct call to the # `project()` command. `project()` sets up some helpful variables that describe source/binary # directories, and the current project version. This is a standard CMake command. project(PaulXStretch VERSION 1.6.0) set(BUILDVERSION 112) # If you've installed JUCE somehow (via a package manager, or directly using the CMake install # target), you'll need to tell this project that it depends on the installed copy of JUCE. If you've # included JUCE directly in your source tree (perhaps as a submodule), you'll need to tell CMake to # include that subdirectory as part of the build. # find_package(JUCE CONFIG REQUIRED) # If you've installed JUCE to your system # or # By default we don't want Xcode schemes to be made for modules, etc set(CMAKE_XCODE_GENERATE_SCHEME OFF) # No ZERO_CHECK target (it helps bust cache for cmake) set(CMAKE_SUPPRESS_REGENERATION true) # prevent install all #set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY true) # Adds all the module sources so they appear correctly in the IDE # Must be set before JUCE is added as a sub-dir (or any targets are made) # https://github.com/juce-framework/JUCE/commit/6b1b4cf7f6b1008db44411f2c8887d71a3348889 set_property(GLOBAL PROPERTY USE_FOLDERS YES) # This is a failed attempt to bury ALL_BUILD in Targets/ # This should be called before any target is made # Bug in Xcode? https://gitlab.kitware.com/cmake/cmake/-/issues/21383 set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "Targets") # Create a /Modules directory in the IDE with the JUCE Module code option(JUCE_ENABLE_MODULE_SOURCE_GROUPS "Show all module sources in IDE projects" ON) # include JUCE add_subdirectory(deps/juce EXCLUDE_FROM_ALL ) # Extend JUCE with CLAP support from https://github.com/free-audio/clap-juce-extensions add_subdirectory(deps/clap-juce-extensions EXCLUDE_FROM_ALL) set (FormatsToBuild VST3 CLAP Standalone) # On Mac, an AU version will be built too if (APPLE) list (APPEND FormatsToBuild AU) endif() # If you are building a VST2 or AAX plugin, CMake needs to be told where to find these SDKs on your # system. This setup should be done before calling `juce_add_plugin`. #juce_set_vst2_sdk_path("../VST2_SDK") #juce_set_aax_sdk_path("../AAX_SDK_2p3p2") if (AAX_SDK_PATH) juce_set_aax_sdk_path (${AAX_SDK_PATH}) if (APPLE OR (NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32"))) list (APPEND AaxFormatsToBuild AAX) endif() endif() #if (VST2_SDK_PATH) # juce_set_vst2_sdk_path (${VST2_SDK_PATH}) # list (APPEND FormatsToBuild VST) #endif() set (MacPList " CFBundleVersion ${BUILDVERSION} CFBundleURLTypes CFBundleURLName com.sonosaurus.paulxstretch CFBundleURLSchemes paulxstretch ") # `juce_add_plugin` adds a static library target with the name passed as the first argument # (AudioPluginExample here). This target is a normal CMake target, but has a lot of extra properties set # up by default. As well as this shared code static library, this function adds targets for each of # the formats specified by the FORMATS arguments. This function accepts many optional arguments. # Check the readme at `docs/CMake API.md` in the JUCE repo for the full list. function(sono_add_custom_plugin_target target_name product_name formats is_instrument no_fftw plugincode) if (is_instrument) set (vst3cats Instrument Network) set (vst2cat "kPlugCategSynth") else() set (vst3cats Fx Network) set (vst2cat "kPlugCategEffect") endif() juce_add_plugin("${target_name}" IS_SYNTH "${is_instrument}" NEEDS_MIDI_INPUT TRUE NEEDS_MIDI_OUTPUT TRUE EDITOR_WANTS_KEYBOARD_FOCUS TRUE COMPANY_NAME "Sonosaurus" BUNDLE_ID "com.sonosaurus.paulxstretch" MICROPHONE_PERMISSION_ENABLED TRUE ICON_BIG "images/paulxstretch_icon_1024_rounded.png" ICON_SMALL "images/paulxstretch_icon_256_rounded.png" NEEDS_WEB_BROWSER FALSE VST2_CATEGORY "${vst2cat}" VST3_CATEGORIES "${vst3cats}" AAX_CATEGORY "AAX_EPlugInCategory_Effect" # mac settings HARDENED_RUNTIME_ENABLED TRUE HARDENED_RUNTIME_OPTIONS "com.apple.security.device.audio-input" PLIST_TO_MERGE "${MacPList}" AU_MAIN_TYPE "kAudioUnitType_MusicEffect" COPY_PLUGIN_AFTER_BUILD FALSE # Set to TRUE to auto-install # other settings... PLUGIN_MANUFACTURER_CODE Sono PLUGIN_CODE ${plugincode} FORMATS ${formats} DESCRIPTION "PaulXStretch - Extreme Timestretching" PRODUCT_NAME "${product_name}") if ("CLAP" IN_LIST formats) # Configure the CLAP plugin clap_juce_extensions_plugin(TARGET "${target_name}" CLAP_ID "com.sonosaurus.paulstretch.clap" CLAP_FEATURES "audio-effect") endif() juce_generate_juce_header("${target_name}") set (HEADER_INCLUDES # Source/PS_Source # Source/WDL ) set (LIB_PATHS "") #set (PLAT_COMPILE_DEFS # $<$:LOGLEVEL=2> # USE_CODEC_OPUS=1 # AOO_TIMEFILTER_CHECK=0 # AOO_STATIC) set(PlatSourceFiles Source/CrossPlatformUtils.h ) set (FFTW_DEPLIBS "") # platform specific stuff if (APPLE) list (APPEND HEADER_INCLUDES deps/mac/include) list (APPEND LIB_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/deps/mac/lib) list (APPEND PlatSourceFiles Source/CrossPlatformUtilsMac.mm) if (no_fftw) # use vDSP list (APPEND PLAT_COMPILE_DEFS PS_USE_VDSP_FFT=1 ) else() list (APPEND FFTW_DEPLIBS fftw3f) endif() elseif (WIN32) list (APPEND HEADER_INCLUDES deps/windows ../asiosdk/common) list (APPEND PlatSourceFiles Source/CrossPlatformUtilsWindows.cpp) message (STATUS "Win generator platform is: ${CMAKE_VS_PLATFORM_NAME}" ) if ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32") list (APPEND LIB_PATHS $<$:${CMAKE_CURRENT_SOURCE_DIR}/deps/windows/Debug32> $<$:${CMAKE_CURRENT_SOURCE_DIR}/deps/windows/Release32> ) else() list (APPEND LIB_PATHS $<$:${CMAKE_CURRENT_SOURCE_DIR}/deps/windows/Debug> $<$:${CMAKE_CURRENT_SOURCE_DIR}/deps/windows/Release> ) endif() list (APPEND PLAT_COMPILE_DEFS JUCE_MODAL_LOOPS_PERMITTED _USE_MATH_DEFINES WINVER=0x0601 _WIN32_WINNT=0x0601 NOMINMAX) if (no_fftw) # use pffft list (APPEND PLAT_COMPILE_DEFS PS_USE_PFFFT=1 ) else() list (APPEND FFTW_DEPLIBS fftw3f mingwex gcc mingw32 msvcrt ) endif() else() # Linux list (APPEND PlatSourceFiles Source/CrossPlatformUtilsLinux.cpp) list ( APPEND PLAT_COMPILE_DEFS JUCE_USE_MP3AUDIOFORMAT=1 ) if (no_fftw) # use pffft list (APPEND PLAT_COMPILE_DEFS PS_USE_PFFFT=1 ) else() list (APPEND FFTW_DEPLIBS fftw3f) endif() endif() set(SourceFiles ${PlatSourceFiles} Source/CustomLookAndFeel.cpp Source/CustomLookAndFeel.h Source/CustomStandaloneFilterApp.cpp Source/CustomStandaloneFilterWindow.h Source/GenericItemChooser.cpp Source/GenericItemChooser.h Source/SonoChoiceButton.cpp Source/SonoChoiceButton.h Source/SonoTextButton.cpp Source/SonoTextButton.h Source/PluginEditor.cpp Source/PluginEditor.h Source/PluginProcessor.cpp Source/PluginProcessor.h Source/RenderSettingsComponent.cpp Source/RenderSettingsComponent.h Source/OptionsView.cpp Source/OptionsView.h Source/envelope_component.cpp Source/envelope_component.h Source/jcdp_envelope.h Source/ps3_BufferingAudioSource.cpp Source/ps3_BufferingAudioSource.h #Source/PS_Source/fftw3.h Source/PS_Source/PaulStretchControl.cpp Source/PS_Source/Stretch.h Source/PS_Source/version.h Source/PS_Source/Player.cpp Source/PS_Source/BinauralBeats.h Source/PS_Source/StretchSource.h Source/PS_Source/ProcessedStretch.cpp Source/PS_Source/Input Source/PS_Source/Input/AInputS.h Source/PS_Source/Input/InputS.h Source/PS_Source/BinauralBeats.cpp Source/PS_Source/ProcessedStretch.h Source/PS_Source/StretchSource.cpp Source/PS_Source/Player.h Source/PS_Source/globals.h Source/PS_Source/Stretch.cpp Source/PS_Source/FreeEdit.h Source/PS_Source/FreeEdit.cpp Source/PS_Source/PaulStretchControl.h Source/PS_Source/Input/AInputS.h Source/PS_Source/Input/InputS.h Source/WDL/resample.h Source/WDL/resample.cpp Source/WDL/wdltypes.h Source/WDL/denormal.h Source/WDL/heapbuf.h Source/pffft/pffft.h Source/pffft/pffft.c ) target_sources("${target_name}" PRIVATE ${SourceFiles} ) # No, we don't want our source buried in extra nested folders set_target_properties("${target_name}" PROPERTIES FOLDER "") # The source tree should uhhh, still look like the source tree, yo source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/Source PREFIX "" FILES ${SourceFiles}) # Move the INTERFACE auto-created JUCE library stuff into its own folder source_group("JUCE Library Code" REGULAR_EXPRESSION "juce_") #target_include_directories("${target_name}" # INTERFACE # $) target_include_directories("${target_name}" PUBLIC ${HEADER_INCLUDES} ) # Require at least C++17 to build `my_target` target_compile_features("${target_name}" PRIVATE cxx_std_17) # This cleans up the folder organization, especially on Xcode. # It tucks the Plugin varieties into a "Targets" folder and generate an Xcode Scheme manually # Xcode scheme generation is turned off globally to limit noise from other targets # The non-hacky way of doing this is via the global PREDEFINED_TARGETS_FOLDER propety # However that doesn't seem to be working in Xcode # Not all plugin types (au, vst) available on each build type (win, macos, linux) foreach(target ${formats} "All") if(TARGET ${target_name}_${target}) set_target_properties(${target_name}_${target} PROPERTIES # Tuck the actual plugin targets into a folder where they won't bother us FOLDER "Targets" # MacOS only: Sets the default executable that Xcode will open on build # For this exact path to to work, manually build the AudioPluginHost.xcodeproj in the JUCE subdir # XCODE_SCHEME_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/deps/juce/extras/AudioPluginHost/Builds/MacOSX/build/Debug/AudioPluginHost.app" # Let us build the target in Xcode XCODE_GENERATE_SCHEME ON) endif() endforeach() target_compile_definitions("${target_name}" PUBLIC JUCE_WEB_BROWSER=0 JUCE_USE_CURL=0 JUCE_VST3_CAN_REPLACE_VST2=0 JUCE_DISPLAY_SPLASH_SCREEN=0 JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP=1 JUCE_USE_WINDOWS_MEDIA_FORMAT=1 JUCE_LOAD_CURL_SYMBOLS_LAZILY=1 JUCE_ASIO=1 JUCE_WASAPI=1 JUCE_DIRECTSOUND=0 JUCE_JACK=1 JUCE_ALSA=1 JUCE_USE_ANDROID_OBOE=1 JUCE_USE_OBOE_STABILIZED_CALLBACK=1 JUCE_LOAD_CURL_SYMBOLS_LAZILY=1 FF_AUDIO_ALLOW_ALLOCATIONS_IN_MEASURE_BLOCK=0 PAULXSTRETCH_BUILD_VERSION="${VERSION}" ${PLAT_COMPILE_DEFS} ) juce_add_binary_data("${target_name}_PSData" SOURCES images/freeze.svg images/loop_icon.svg images/passthru.svg images/passthru_enabled.svg images/pause_icon.svg images/play_icon.svg images/power.svg images/power_sel.svg images/record_input.svg images/record_input_active.svg images/record_output.svg images/record_output_active.svg images/skipback_icon.svg ) set_target_properties(${target_name}_PSData PROPERTIES FOLDER "Targets") if (UNIX AND NOT APPLE) target_compile_options("${target_name}_PSData" PRIVATE -fPIC ) find_library(FFTWF_LIB fftw3f) if (NOT FFTWF_LIB) message(FATAL_ERROR "fftw3f library not found, please install libfftw3f develop package") endif() if (JUCE_LINUX_TARGET_ARCHITECTURE MATCHES "arm" ) message(STATUS "ARM platform, adding -march=native") target_compile_options(${target_name} PUBLIC -march=native ) endif() if (TARGET ${target_name}_Standalone) # make linux executable all lower case string(TOLOWER ${target_name} tmptargname) set_target_properties("${target_name}_Standalone" PROPERTIES OUTPUT_NAME ${tmptargname} ) endif() endif() target_link_directories("${target_name}" INTERFACE ${LIB_PATHS} ) target_link_libraries("${target_name}" PRIVATE juce::juce_audio_utils juce::juce_dsp juce::juce_audio_plugin_client juce::juce_cryptography ${target_name}_PSData ${FFTW_DEPLIBS} PUBLIC juce::juce_recommended_config_flags juce::juce_recommended_lto_flags # juce::juce_recommended_warning_flags ) endfunction() # most of the targets sono_add_custom_plugin_target(PaulXStretch PaulXStretch "${FormatsToBuild}" FALSE FALSE "Pxst") if (AaxFormatsToBuild) # AAX builds without fftw sono_add_custom_plugin_target(PaulXStretchAAX PaulXStretch "${AaxFormatsToBuild}" FALSE TRUE "Pxst") endif() # Mobile targets #sono_add_custom_plugin_target(PaulXStretch "AUv3 Standalone" FALSE "NBus") # add VSTi target # sono_add_custom_plugin_target(PaulXStretchInst "PaulXStretchInstrument" "VST3" TRUE "IBus")