diff --git a/.gitignore b/.gitignore index 08319ee3..0208e9ab 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ scripts/soloud_codegen.py glue/rpgmaker_soloud.rb *.lastcodeanalysissucceeded *.bak +CMakeLists.txt.user diff --git a/AUTHORS b/AUTHORS index 8f9a7e17..b9a255bf 100644 --- a/AUTHORS +++ b/AUTHORS @@ -28,3 +28,4 @@ Danny Angelo Carminati Grein https://github.com/fungos Igor Ivanov https://github.com/laptabrok Matthew O'Connell https://github.com/matthew-oconnell Boris Carvajal https://github.com/BorisCarvajal +Bradley Clemetson https://github.com/bradc6 \ No newline at end of file diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index fb5369e7..4c07a893 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -1,32 +1,68 @@ -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 3.0) +project(SoLoud) -project (SoLoud) +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) -set (CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}") -set (CMAKE_POSITION_INDEPENDENT_CODE ON) -#INCLUDE (StandartIncludes) +include(OptionDependentOnPackage) +include(PrintOptionStatus) -include_directories (../include) +option(SOLOUD_DYNAMIC "Set to ON to build dynamic SoLoud" OFF) +print_option_status (SOLOUD_DYNAMIC "Build dynamic library") -include (Configure.cmake) -#INCLUDE (InstallIncludes.cmake) -#INCLUDE (InstallStaticData.cmake) +option(SOLOUD_STATIC "Set to ON to build static SoLoud" ON) +print_option_status (SOLOUD_STATIC "Build static library") -if (UNIX AND NOT WIN32 AND NOT APPLE) - if (CMAKE_SIZEOF_VOID_P MATCHES "8") - set (LIB_POSTFIX "64" CACHE STRING "suffix for 32/64 dir placement") - mark_as_advanced (LIB_POSTFIX) - endif () -endif () -if (NOT DEFINED LIB_POSTFIX) - set (LIB_POSTFIX "") -endif () +option(SOLOUD_BUILD_DEMOS "Set to ON for building demos" OFF) +option(SOLOUD_ENABLE_BACKEND_NULL "Set to ON for building NULL backend" ON) +option(SOLOUD_ENABLE_BACKEND_SDL2 "Set to ON for building SDL2 backend" OFF) +option(SOLOUD_ENABLE_BACKEND_ALSA "Set to ON for building the ALSA backend" OFF) +option(SOLOUD_ENABLE_BACKEND_PIPEWIRE "Set to ON for building PIPEWIRE backend" OFF) +option(SOLOUD_ENABLE_BACKEND_COREAUDIO "Set to ON for building CoreAudio backend" OFF) +option(SOLOUD_ENABLE_BACKEND_OPENSLES "Set to ON for building OpenSLES backend" OFF) +option(SOLOUD_ENABLE_BACKEND_XAUDIO2 "Set to ON for building XAudio2 backend" OFF) +option(SOLOUD_ENABLE_BACKEND_WINMM "Set to ON for building WINMM backend" OFF) +option(SOLOUD_ENABLE_BACKEND_WASAPI "Set to ON for building WASAPI backend" OFF) +option(SOLOUD_AUTO_DETECT_BACKENDS "Attempt to enable backends based on what is available" ON) + +if(SOLOUD_AUTO_DETECT_BACKENDS) + find_package(SDL2) + set(SOLOUD_ENABLE_BACKEND_SDL2 ${SDL2_FOUND}) + find_package(ALSA) + set(SOLOUD_ENABLE_BACKEND_ALSA ${ALSA_FOUND}) + find_package(PipeWire) + set(SOLOUD_ENABLE_BACKEND_PIPEWIRE ${PipeWire_FOUND}) + + if(APPLE) + set(SOLOUD_BACKEND_COREAUDIO ON) + endif() + + find_package(OpenSLES) + set(SOLOUD_ENABLE_BACKEND_OPENSLES ${OPENSLES_FOUND}) +endif() + +if(SOLOUD_BUILD_DEMOS) + set(SOLOUD_STATIC ON) +endif() + +print_option_status (SOLOUD_BUILD_DEMOS "Build demos") +print_option_status (SOLOUD_AUTO_DETECT_BACKENDS "Auto Detect Backends") +print_option_status (SOLOUD_ENABLE_BACKEND_NULL "NULL backend") +print_option_status (SOLOUD_BACKEND_SDL2 "SDL2 backend") +print_option_status (SOLOUD_ENABLE_BACKEND_ALSA "ALSA backend") +print_option_status (SOLOUD_ENABLE_BACKEND_PIPEWIRE "PipeWire backend") +print_option_status (SOLOUD_BACKEND_COREAUDIO "CoreAudio backend") +print_option_status (SOLOUD_BACKEND_OPENSLES "OpenSLES backend") +print_option_status (SOLOUD_BACKEND_XAUDIO2 "XAudio2 backend") +print_option_status (SOLOUD_BACKEND_WINMM "WINMM backend") +print_option_status (SOLOUD_BACKEND_WASAPI "WASAPI backend") + +#Establish some basic mappings to filesystem directories +get_filename_component(SOLOUD_ROOT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) include (src.cmake) # Demos -IF (SOLOUD_BUILD_DEMOS) +if(SOLOUD_BUILD_DEMOS) include (demos.cmake) endif () -include (InstallExport) diff --git a/contrib/Configure.cmake b/contrib/Configure.cmake deleted file mode 100644 index b627855c..00000000 --- a/contrib/Configure.cmake +++ /dev/null @@ -1,33 +0,0 @@ -include (OptionDependentOnPackage) -include (PrintOptionStatus) - -option (SOLOUD_DYNAMIC "Set to ON to build dynamic SoLoud" OFF) -print_option_status (SOLOUD_DYNAMIC "Build dynamic library") - -option (SOLOUD_STATIC "Set to ON to build static SoLoud" ON) -print_option_status (SOLOUD_STATIC "Build static library") - -# TODO: -option (SOLOUD_BUILD_DEMOS "Set to ON for building demos" OFF) -print_option_status (SOLOUD_BUILD_DEMOS "Build demos") - -option (SOLOUD_BACKEND_NULL "Set to ON for building NULL backend" ON) -print_option_status (SOLOUD_BACKEND_NULL "NULL backend") - -option (SOLOUD_BACKEND_SDL2 "Set to ON for building SDL2 backend" ON) -print_option_status (SOLOUD_BACKEND_SDL2 "SDL2 backend") - -option (SOLOUD_BACKEND_COREAUDIO "Set to ON for building CoreAudio backend" OFF) -print_option_status (SOLOUD_BACKEND_COREAUDIO "CoreAudio backend") - -option (SOLOUD_BACKEND_OPENSLES "Set to ON for building OpenSLES backend" OFF) -print_option_status (SOLOUD_BACKEND_OPENSLES "OpenSLES backend") - -option (SOLOUD_BACKEND_XAUDIO2 "Set to ON for building XAudio2 backend" OFF) -print_option_status (SOLOUD_BACKEND_XAUDIO2 "XAudio2 backend") - -option (SOLOUD_BACKEND_WINMM "Set to ON for building WINMM backend" OFF) -print_option_status (SOLOUD_BACKEND_WINMM "WINMM backend") - -option (SOLOUD_BACKEND_WASAPI "Set to ON for building WASAPI backend" OFF) -print_option_status (SOLOUD_BACKEND_WASAPI "WASAPI backend") diff --git a/contrib/cmake/FindOpenSLES.cmake b/contrib/cmake/FindOpenSLES.cmake new file mode 100644 index 00000000..e27539a7 --- /dev/null +++ b/contrib/cmake/FindOpenSLES.cmake @@ -0,0 +1,28 @@ +# - Find OpenSLES +# Find the OpenSLES includes and libraries +# +# OPENSLES_INCLUDE_DIR - where to find dsound.h +# OPENSLES_LIBRARIES - List of libraries when using dsound. +# OPENSLES_FOUND - True if dsound found. + +get_property(_FIND_LIBRARY_USE_LIB64_PATHS GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS) +set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS 1) + +find_path(OpenSLES_INCLUDE_DIR SLES/OpenSLES.h) +find_library(OpenSLES_LIBRARY NAMES OpenSLES) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OpenSLES DEFAULT_MSG OpenSLES_INCLUDE_DIR OpenSLES_LIBRARY) + +if(OpenSLES_FOUND) + set(OpenSLES_INCLUDE_DIRS ${OPENSLES_INCLUDE_DIR}) + set(OpenSLES_LIBRARIES ${OPENSLES_LIBRARY}) +else(OpenSLES_FOUND) + if (OpenSLES_FIND_REQUIRED) + message(FATAL_ERROR "Could NOT find OPENSLES") + endif() +endif(OpenSLES_FOUND) + +mark_as_advanced(OpenSLES_INCLUDE_DIR OpenSLES_LIBRARY) + +set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS ${_FIND_LIBRARY_USE_LIB64_PATHS}) diff --git a/contrib/cmake/FindPipeWire.cmake b/contrib/cmake/FindPipeWire.cmake new file mode 100644 index 00000000..c90c3e08 --- /dev/null +++ b/contrib/cmake/FindPipeWire.cmake @@ -0,0 +1,122 @@ +#.rst: +# FindPipeWire +# ------- +# +# Try to find PipeWire on a Unix system. +# +# This will define the following variables: +# +# ``PipeWire_FOUND`` +# True if (the requested version of) PipeWire is available +# ``PipeWire_VERSION`` +# The version of PipeWire +# ``PipeWire_LIBRARIES`` +# This can be passed to target_link_libraries() instead of the ``PipeWire::PipeWire`` +# target +# ``PipeWire_INCLUDE_DIRS`` +# This should be passed to target_include_directories() if the target is not +# used for linking +# ``PipeWire_DEFINITIONS`` +# This should be passed to target_compile_options() if the target is not +# used for linking +# +# If ``PipeWire_FOUND`` is TRUE, it will also define the following imported target: +# +# ``PipeWire::PipeWire`` +# The PipeWire library +# +# In general we recommend using the imported target, as it is easier to use. +# Bear in mind, however, that if the target is in the link interface of an +# exported library, it must be made available by the package config file. + +#============================================================================= +# Copyright 2014 Alex Merry +# Copyright 2014 Martin Gräßlin +# Copyright 2018-2020 Jan Grulich +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +# Use pkg-config to get the directories and then use these values +# in the FIND_PATH() and FIND_LIBRARY() calls +find_package(PkgConfig QUIET) + +pkg_search_module(PKG_PipeWire QUIET libpipewire-0.3 libpipewire-0.2) +pkg_search_module(PKG_Spa QUIET libspa-0.2 libspa-0.1) + +set(PipeWire_DEFINITIONS "${PKG_PipeWire_CFLAGS}" "${PKG_Spa_CFLAGS}") +set(PipeWire_VERSION "${PKG_PipeWire_VERSION}") + +find_path(PipeWire_INCLUDE_DIRS + NAMES + pipewire/pipewire.h + HINTS + ${PKG_PipeWire_INCLUDE_DIRS} + ${PKG_PipeWire_INCLUDE_DIRS}/pipewire-0.3 +) + +find_path(Spa_INCLUDE_DIRS + NAMES + spa/param/props.h + HINTS + ${PKG_Spa_INCLUDE_DIRS} + ${PKG_Spa_INCLUDE_DIRS}/spa-0.2 +) + +find_library(PipeWire_LIBRARIES + NAMES + pipewire-0.3 + pipewire-0.2 + HINTS + ${PKG_PipeWire_LIBRARY_DIRS} +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(PipeWire + FOUND_VAR + PipeWire_FOUND + REQUIRED_VARS + PipeWire_LIBRARIES + PipeWire_INCLUDE_DIRS + Spa_INCLUDE_DIRS + VERSION_VAR + PipeWire_VERSION +) + +if(PipeWire_FOUND AND NOT TARGET PipeWire::PipeWire) + add_library(PipeWire::PipeWire UNKNOWN IMPORTED) + set_target_properties(PipeWire::PipeWire PROPERTIES + IMPORTED_LOCATION "${PipeWire_LIBRARIES}" + INTERFACE_COMPILE_OPTIONS "${PipeWire_DEFINITIONS}" + INTERFACE_INCLUDE_DIRECTORIES "${PipeWire_INCLUDE_DIRS};${Spa_INCLUDE_DIRS}" + ) +endif() + +mark_as_advanced(PipeWire_LIBRARIES PipeWire_INCLUDE_DIRS) + +include(FeatureSummary) +set_package_properties(PipeWire PROPERTIES + URL "https://www.pipewire.org" + DESCRIPTION "PipeWire - multimedia processing" +) \ No newline at end of file diff --git a/contrib/cmake/Install.cmake b/contrib/cmake/Install.cmake deleted file mode 100644 index bc2d6527..00000000 --- a/contrib/cmake/Install.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# Required Vars: -# ${TARGET_NAME} - -SET (INSTALL_BINDIR bin) -IF(WIN32) - SET(INSTALL_LIBDIR bin) - SET(INSTALL_ARCHIVEDIR lib) -ELSE(WIN32) - SET(INSTALL_LIBDIR lib${LIB_POSTFIX}) - SET(INSTALL_ARCHIVEDIR lib${LIB_POSTFIX}) -ENDIF(WIN32) - -SET (PROJECT_NAME_LOWERCASE) -STRING (TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWERCASE) -INSTALL ( - TARGETS ${TARGET_NAME} - EXPORT ${PROJECT_NAME_LOWERCASE}-config - RUNTIME DESTINATION ${INSTALL_BINDIR} - BUNDLE DESTINATION ${INSTALL_BINDIR} - LIBRARY DESTINATION ${INSTALL_LIBDIR} - ARCHIVE DESTINATION ${INSTALL_ARCHIVEDIR} -) diff --git a/contrib/cmake/InstallExport.cmake b/contrib/cmake/InstallExport.cmake deleted file mode 100644 index a9fa0a8a..00000000 --- a/contrib/cmake/InstallExport.cmake +++ /dev/null @@ -1,38 +0,0 @@ -# Installs export targets (i.e. cmake config files) into location -# specified for OS. -# Installs ${PROJECT_NAME}-SetThirdParties.cmake too if such file -# is found in ${PROJECT_SOURCE_DIR}. - -SET (EV_CMAKE_EXPORT_DIR share/${PROJECT_NAME}/cmake) - -IF (WIN32) - SET (EV_CMAKE_EXPORT_DIR cmake) -ENDIF () - -SET (PROJECT_NAME_LOWERCASE) -STRING (TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWERCASE) -INSTALL ( - EXPORT ${PROJECT_NAME_LOWERCASE}-config - DESTINATION ${EV_CMAKE_EXPORT_DIR} -) - -SET (EV_STP_FILENAME ${PROJECT_SOURCE_DIR}/${PROJECT_NAME}-SetThirdParties.cmake) -IF (EXISTS ${EV_STP_FILENAME}) - INSTALL ( - FILES ${EV_STP_FILENAME} - DESTINATION ${EV_CMAKE_EXPORT_DIR} - ) -ENDIF () - -SET (EV_SETTINGS_FILENAME ${PROJECT_SOURCE_DIR}/${PROJECT_NAME}-Settings.cmake) -IF (NOT EXISTS ${EV_SETTINGS_FILENAME}) - # This file may be configured => it placed in binary dir - SET (EV_SETTINGS_FILENAME ${PROJECT_BINARY_DIR}/${PROJECT_NAME}-Settings.cmake) -ENDIF () - -IF (EXISTS ${EV_SETTINGS_FILENAME}) - INSTALL ( - FILES ${EV_SETTINGS_FILENAME} - DESTINATION ${EV_CMAKE_EXPORT_DIR} - ) -ENDIF () diff --git a/contrib/demos.cmake b/contrib/demos.cmake index 43f11442..b7a31424 100644 --- a/contrib/demos.cmake +++ b/contrib/demos.cmake @@ -1,38 +1,104 @@ -set (HEADER_PATH ../include) -set (SOURCE_PATH ../demos) - -function (soloud_add_demo name sources) - set (TARGET_NAME SoLoud_${name}) - add_executable (${TARGET_NAME} ${sources}) - target_link_libraries (${TARGET_NAME} soloud) - include (Install) -endfunction() - -include_directories (${SOURCE_PATH}/common) -include_directories (${SOURCE_PATH}/common/imgui) - - -# soloud_add_demo(c_test ${SOURCE_PATH}/c_test/main.c) -soloud_add_demo(enumerate ${SOURCE_PATH}/enumerate/main.cpp) -# soloud_add_demo(env ${SOURCE_PATH}/env/main.cpp) -# soloud_add_demo(megademo -# ${SOURCE_PATH}/megademo/3dtest.cpp -# ${SOURCE_PATH}/megademo/main.cpp -# ${SOURCE_PATH}/megademo/mixbusses.cpp -# ${SOURCE_PATH}/megademo/monotone.cpp -# ${SOURCE_PATH}/megademo/multimusic.cpp -# ${SOURCE_PATH}/megademo/pewpew.cpp -# ${SOURCE_PATH}/megademo/radiogaga.cpp -# ${SOURCE_PATH}/megademo/space.cpp -# ${SOURCE_PATH}/megademo/speechfilter.cpp -# ${SOURCE_PATH}/megademo/tedsid.cpp -# ${SOURCE_PATH}/megademo/virtualvoices.cpp -# ) -soloud_add_demo(null ${SOURCE_PATH}/null/main.cpp) -# soloud_add_demo(piano -# ${SOURCE_PATH}/piano/main.cpp -# ${SOURCE_PATH}/piano/soloud_basicwave.cpp -# ${SOURCE_PATH}/piano/soloud_padsynth.cpp -# ) -soloud_add_demo(simplest ${SOURCE_PATH}/simplest/main.cpp) -soloud_add_demo(welcome ${SOURCE_PATH}/welcome/main.cpp) +set(SOLOUD_DEMO_DIRECTORY ${SOLOUD_ROOT_DIRECTORY}/demos) + + +############################## +#Backing libraries for Demo +############################## +set(SOLOUD_DEMO_COMMON ${SOLOUD_DEMO_DIRECTORY}/common) + +set(OpenGL_GL_PREFERENCE "GLVND") +find_package(OpenGL) + +set(SOLOUD_DEMO_GLEW_DIR ${SOLOUD_DEMO_COMMON}/glew/GL) +set(SOLOUD_DEMO_GLEW_SOURCES + ${SOLOUD_DEMO_GLEW_DIR}/glew.c + ${SOLOUD_DEMO_GLEW_DIR}/glew.h + ${SOLOUD_DEMO_GLEW_DIR}/glxew.h + ${SOLOUD_DEMO_GLEW_DIR}/wglew.h +) +add_library(soloud-demo-glew STATIC ${SOLOUD_DEMO_GLEW_SOURCES}) +target_include_directories(soloud-demo-glew PUBLIC ${SOLOUD_DEMO_COMMON}/glew) + +set(SOLOUD_DEMO_IMGUI_DIR ${SOLOUD_DEMO_COMMON}/imgui) +set(SOLOUD_IMGUI_SOURCES + ${SOLOUD_DEMO_IMGUI_DIR}/imconfig.h + ${SOLOUD_DEMO_IMGUI_DIR}/imgui.cpp + ${SOLOUD_DEMO_IMGUI_DIR}/imgui_demo.cpp + ${SOLOUD_DEMO_IMGUI_DIR}/imgui_draw.cpp + ${SOLOUD_DEMO_IMGUI_DIR}/imgui.h + ${SOLOUD_DEMO_IMGUI_DIR}/imgui_internal.h + ${SOLOUD_DEMO_IMGUI_DIR}/stb_rect_pack.h + ${SOLOUD_DEMO_IMGUI_DIR}/stb_textedit.h + ${SOLOUD_DEMO_IMGUI_DIR}/stb_truetype.h + ) +add_library(soloud-imgui STATIC ${SOLOUD_IMGUI_SOURCES}) +target_include_directories(soloud-imgui PUBLIC ${SOLOUD_DEMO_COMMON}/imgui) + + +set(SOLOUD_DEMO_FRAMEWORK_SOURCES + ${SOLOUD_DEMO_COMMON}/soloud_demo_framework.cpp + ${SOLOUD_DEMO_COMMON}/soloud_demo_framework.h + ${SOLOUD_DEMO_COMMON}/stb_image.h + ) +add_library(soloud-demo-framework STATIC ${SOLOUD_DEMO_FRAMEWORK_SOURCES}) +target_include_directories(soloud-demo-framework PUBLIC ${SOLOUD_DEMO_COMMON}) +target_link_libraries(soloud-demo-framework PUBLIC soloud-imgui soloud-demo-glew OpenGL::GL) + +############################## +#Demos +############################## + +#Simplest +add_executable(simplest ${SOLOUD_DEMO_DIRECTORY}/simplest/main.cpp) +target_link_libraries(simplest PUBLIC soloud) + +#C API test +add_executable(ctest ${SOLOUD_DEMO_DIRECTORY}/c_test/main.c) +target_link_libraries(ctest PUBLIC soloud) + +#Welcome +add_executable(welcome ${SOLOUD_DEMO_DIRECTORY}/welcome/main.cpp) +target_link_libraries(welcome PUBLIC soloud) + +#env +add_executable(env ${SOLOUD_DEMO_DIRECTORY}/env/main.cpp) +target_link_libraries(env PUBLIC soloud soloud-demo-framework) + +#null +add_executable(null ${SOLOUD_DEMO_DIRECTORY}/null/main.cpp) +target_link_libraries(null PUBLIC soloud) + +#piana +set(SOLOUD_DEMO_PIANO_SOURCE_DIR ${SOLOUD_DEMO_DIRECTORY}/piano) +set(SOLOUD_DEMO_PIANO_SOURCES + ${SOLOUD_DEMO_PIANO_SOURCE_DIR}/main.cpp + ${SOLOUD_DEMO_PIANO_SOURCE_DIR}/RtMidi.cpp + ${SOLOUD_DEMO_PIANO_SOURCE_DIR}/RtMidi.h + ${SOLOUD_DEMO_PIANO_SOURCE_DIR}/soloud_basicwave.cpp + ${SOLOUD_DEMO_PIANO_SOURCE_DIR}/soloud_basicwave.h + ${SOLOUD_DEMO_PIANO_SOURCE_DIR}/soloud_padsynth.cpp + ${SOLOUD_DEMO_PIANO_SOURCE_DIR}/soloud_padsynth.h + ) +add_executable(piano ${SOLOUD_DEMO_PIANO_SOURCES}) +target_link_libraries(piano PUBLIC soloud soloud-demo-framework) + +#MegaDemo +set(SOLOUD_DEMO_MEGADEMO_SOURCE_DIR ${SOLOUD_DEMO_DIRECTORY}/megademo) +set(SOLOUD_DEMO_MEGADEMO_SOURCES + ${SOLOUD_DEMO_MEGADEMO_SOURCE_DIR}/3dtest.cpp + ${SOLOUD_DEMO_MEGADEMO_SOURCE_DIR}/main.cpp + ${SOLOUD_DEMO_MEGADEMO_SOURCE_DIR}/mixbusses.cpp + ${SOLOUD_DEMO_MEGADEMO_SOURCE_DIR}/monotone.cpp + ${SOLOUD_DEMO_MEGADEMO_SOURCE_DIR}/multimusic.cpp + ${SOLOUD_DEMO_MEGADEMO_SOURCE_DIR}/pewpew.cpp + ${SOLOUD_DEMO_MEGADEMO_SOURCE_DIR}/radiogaga.cpp + ${SOLOUD_DEMO_MEGADEMO_SOURCE_DIR}/space.cpp + ${SOLOUD_DEMO_MEGADEMO_SOURCE_DIR}/speechfilter.cpp + ${SOLOUD_DEMO_MEGADEMO_SOURCE_DIR}/tedsid.cpp + ${SOLOUD_DEMO_MEGADEMO_SOURCE_DIR}/virtualvoices.cpp + ${SOLOUD_DEMO_MEGADEMO_SOURCE_DIR}/wavformats.cpp + ${SOLOUD_DEMO_MEGADEMO_SOURCE_DIR}/speakers.cpp + ${SOLOUD_DEMO_MEGADEMO_SOURCE_DIR}/thebutton.cpp +) +add_executable(megademo ${SOLOUD_DEMO_MEGADEMO_SOURCES}) +target_link_libraries(megademo PUBLIC soloud soloud-demo-framework) diff --git a/contrib/src.cmake b/contrib/src.cmake index 0bda84e5..b5e74296 100644 --- a/contrib/src.cmake +++ b/contrib/src.cmake @@ -1,223 +1,216 @@ -set (TARGET_NAME soloud) - -set (HEADER_PATH ../include) -set (SOURCE_PATH ../src) - -set (LINK_LIBRARIES) - -# Headers -set (TARGET_HEADERS - ${HEADER_PATH}/soloud.h - ${HEADER_PATH}/soloud_audiosource.h - ${HEADER_PATH}/soloud_bassboostfilter.h - ${HEADER_PATH}/soloud_biquadresonantfilter.h - ${HEADER_PATH}/soloud_bus.h - ${HEADER_PATH}/soloud_c.h - ${HEADER_PATH}/soloud_dcremovalfilter.h - ${HEADER_PATH}/soloud_echofilter.h - ${HEADER_PATH}/soloud_error.h - ${HEADER_PATH}/soloud_fader.h - ${HEADER_PATH}/soloud_fft.h - ${HEADER_PATH}/soloud_fftfilter.h - ${HEADER_PATH}/soloud_file.h - ${HEADER_PATH}/soloud_file_hack_off.h - ${HEADER_PATH}/soloud_file_hack_on.h - ${HEADER_PATH}/soloud_filter.h - ${HEADER_PATH}/soloud_flangerfilter.h - ${HEADER_PATH}/soloud_internal.h - ${HEADER_PATH}/soloud_lofifilter.h - ${HEADER_PATH}/soloud_monotone.h - ${HEADER_PATH}/soloud_openmpt.h - ${HEADER_PATH}/soloud_queue.h - ${HEADER_PATH}/soloud_robotizefilter.h - ${HEADER_PATH}/soloud_sfxr.h - ${HEADER_PATH}/soloud_speech.h - ${HEADER_PATH}/soloud_tedsid.h - ${HEADER_PATH}/soloud_thread.h - ${HEADER_PATH}/soloud_vic.h - ${HEADER_PATH}/soloud_vizsn.h - ${HEADER_PATH}/soloud_wav.h - ${HEADER_PATH}/soloud_waveshaperfilter.h - ${HEADER_PATH}/soloud_wavstream.h -) +set(SOLOUD_PUBLIC_HEADERS_DIR ${SOLOUD_ROOT_DIRECTORY}/include) +set(SOLOUD_SOURCE_PATH_DIR ${SOLOUD_ROOT_DIRECTORY}/src) +#Stub the existence of the libraries +if(SOLOUD_STATIC) + add_library(soloud STATIC) +endif() +if(SOLOUD_DYNAMIC) + add_library(soloud-dynamic SHARED) + set_target_properties(soloud-dynamic + PROPERTIES + POSITION_INDEPENDENT_CODE ON) +endif() -# Core -set (CORE_PATH ${SOURCE_PATH}/core) -set (CORE_SOURCES - ${CORE_PATH}/soloud.cpp - ${CORE_PATH}/soloud_audiosource.cpp - ${CORE_PATH}/soloud_bus.cpp - ${CORE_PATH}/soloud_core_3d.cpp - ${CORE_PATH}/soloud_core_basicops.cpp - ${CORE_PATH}/soloud_core_faderops.cpp - ${CORE_PATH}/soloud_core_filterops.cpp - ${CORE_PATH}/soloud_core_getters.cpp - ${CORE_PATH}/soloud_core_setters.cpp - ${CORE_PATH}/soloud_core_voicegroup.cpp - ${CORE_PATH}/soloud_core_voiceops.cpp - ${CORE_PATH}/soloud_fader.cpp - ${CORE_PATH}/soloud_fft.cpp - ${CORE_PATH}/soloud_fft_lut.cpp - ${CORE_PATH}/soloud_file.cpp - ${CORE_PATH}/soloud_filter.cpp - ${CORE_PATH}/soloud_queue.cpp - ${CORE_PATH}/soloud_thread.cpp +function(apply_to_soloud_libraries FUNCTION_NAME) + if(SOLOUD_STATIC) + cmake_language(CALL ${FUNCTION_NAME} soloud ${ARGN}) + endif() + if(SOLOUD_DYNAMIC) + cmake_language(CALL ${FUNCTION_NAME} soloud-dynamic ${ARGN}) + endif() +endfunction() + +set(SOLOUD_SOURCES) +###################################### +#Core +###################################### +set(SOLOUD_CORE_SOURCE_DIR ${SOLOUD_SOURCE_PATH_DIR}/core) +set(SOLOUD_CORE_SOURCES + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud.h + ${SOLOUD_CORE_SOURCE_DIR}/soloud.cpp + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_audiosource.h + ${SOLOUD_CORE_SOURCE_DIR}/soloud_audiosource.cpp + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_bassboostfilter.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_biquadresonantfilter.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_bus.h + ${SOLOUD_CORE_SOURCE_DIR}/soloud_bus.cpp + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_c.h + ${SOLOUD_CORE_SOURCE_DIR}/soloud_core_3d.cpp + ${SOLOUD_CORE_SOURCE_DIR}/soloud_core_basicops.cpp + ${SOLOUD_CORE_SOURCE_DIR}/soloud_core_faderops.cpp + ${SOLOUD_CORE_SOURCE_DIR}/soloud_core_filterops.cpp + ${SOLOUD_CORE_SOURCE_DIR}/soloud_core_getters.cpp + ${SOLOUD_CORE_SOURCE_DIR}/soloud_core_setters.cpp + ${SOLOUD_CORE_SOURCE_DIR}/soloud_core_voicegroup.cpp + ${SOLOUD_CORE_SOURCE_DIR}/soloud_core_voiceops.cpp + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_dcremovalfilter.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_echofilter.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_error.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_fader.h + ${SOLOUD_CORE_SOURCE_DIR}/soloud_fader.cpp + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_fft.h + ${SOLOUD_CORE_SOURCE_DIR}/soloud_fft.cpp + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_fftfilter.h + ${SOLOUD_CORE_SOURCE_DIR}/soloud_fft_lut.cpp + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_file.h + ${SOLOUD_CORE_SOURCE_DIR}/soloud_file.cpp + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_file_hack_off.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_file_hack_on.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_filter.h + ${SOLOUD_CORE_SOURCE_DIR}/soloud_filter.cpp + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_flangerfilter.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_internal.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_lofifilter.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_monotone.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_openmpt.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_queue.h + ${SOLOUD_CORE_SOURCE_DIR}/soloud_queue.cpp + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_robotizefilter.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_sfxr.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_speech.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_tedsid.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_thread.h + ${SOLOUD_CORE_SOURCE_DIR}/soloud_thread.cpp + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_vic.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_vizsn.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_wav.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_waveshaperfilter.h + ${SOLOUD_PUBLIC_HEADERS_DIR}/soloud_wavstream.h ) - - -# Audiosources -set (AUDIOSOURCES_PATH ${SOURCE_PATH}/audiosource) -set (AUDIOSOURCES_SOURCES - ${AUDIOSOURCES_PATH}/monotone/soloud_monotone.cpp - ${AUDIOSOURCES_PATH}/openmpt/soloud_openmpt.cpp - ${AUDIOSOURCES_PATH}/openmpt/soloud_openmpt_dll.c - ${AUDIOSOURCES_PATH}/sfxr/soloud_sfxr.cpp - ${AUDIOSOURCES_PATH}/speech/darray.cpp - ${AUDIOSOURCES_PATH}/speech/klatt.cpp - ${AUDIOSOURCES_PATH}/speech/resonator.cpp - ${AUDIOSOURCES_PATH}/speech/soloud_speech.cpp - ${AUDIOSOURCES_PATH}/speech/tts.cpp - ${AUDIOSOURCES_PATH}/tedsid/sid.cpp - ${AUDIOSOURCES_PATH}/tedsid/soloud_tedsid.cpp - ${AUDIOSOURCES_PATH}/tedsid/ted.cpp - ${AUDIOSOURCES_PATH}/vic/soloud_vic.cpp - ${AUDIOSOURCES_PATH}/vizsn/soloud_vizsn.cpp - ${AUDIOSOURCES_PATH}/wav/dr_impl.cpp - ${AUDIOSOURCES_PATH}/wav/soloud_wav.cpp - ${AUDIOSOURCES_PATH}/wav/soloud_wavstream.cpp - ${AUDIOSOURCES_PATH}/wav/stb_vorbis.c +source_group ("Core" FILES ${SOLOUD_CORE_SOURCES}) +list(APPEND SOLOUD_SOURCES ${SOLOUD_CORE_SOURCES}) + +###################################### +#Audiosources +###################################### +set(SOLOUD_AUDIOSOURCES_DIR ${SOLOUD_SOURCE_PATH_DIR}/audiosource) +set(SOLOUD_AUDIOSOURCES_SOURCES + ${SOLOUD_AUDIOSOURCES_DIR}/monotone/soloud_monotone.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/openmpt/soloud_openmpt.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/openmpt/soloud_openmpt_dll.c + ${SOLOUD_AUDIOSOURCES_DIR}/sfxr/soloud_sfxr.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/speech/darray.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/speech/klatt.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/speech/resonator.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/speech/soloud_speech.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/speech/tts.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/tedsid/sid.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/tedsid/soloud_tedsid.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/tedsid/ted.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/vic/soloud_vic.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/vizsn/soloud_vizsn.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/wav/dr_impl.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/wav/soloud_wav.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/wav/soloud_wavstream.cpp + ${SOLOUD_AUDIOSOURCES_DIR}/wav/stb_vorbis.c ) - - -# Backends -set (BACKENDS_PATH ${SOURCE_PATH}/backend) -set (BACKENDS_SOURCES) - -if (SOLOUD_BACKEND_NULL) - set (BACKENDS_SOURCES - ${BACKENDS_SOURCES} - ${BACKENDS_PATH}/null/soloud_null.cpp +source_group ("AudioSources" FILES ${SOLOUD_AUDIOSOURCES_SOURCES}) +list(APPEND SOLOUD_SOURCES ${SOLOUD_AUDIOSOURCES_SOURCES}) + +###################################### +#Filters +###################################### +set (SOLOUD_FILTERS_PATH_DIR ${SOLOUD_SOURCE_PATH_DIR}/filter) +set (SOLOUD_FILTERS_SOURCES + ${SOLOUD_FILTERS_PATH_DIR}/soloud_bassboostfilter.cpp + ${SOLOUD_FILTERS_PATH_DIR}/soloud_biquadresonantfilter.cpp + ${SOLOUD_FILTERS_PATH_DIR}/soloud_dcremovalfilter.cpp + ${SOLOUD_FILTERS_PATH_DIR}/soloud_echofilter.cpp + ${SOLOUD_FILTERS_PATH_DIR}/soloud_fftfilter.cpp + ${SOLOUD_FILTERS_PATH_DIR}/soloud_flangerfilter.cpp + ${SOLOUD_FILTERS_PATH_DIR}/soloud_lofifilter.cpp + ${SOLOUD_FILTERS_PATH_DIR}/soloud_robotizefilter.cpp + ${SOLOUD_FILTERS_PATH_DIR}/soloud_waveshaperfilter.cpp +) +source_group ("Filters" FILES ${SOLOUD_FILTERS_SOURCES}) +list(APPEND SOLOUD_SOURCES ${SOLOUD_FILTERS_SOURCES}) + +############################################ +#C API +############################################ +set(SOLOUD_C_API_SOURCE_DIR ${SOLOUD_SOURCE_PATH_DIR}/c_api) +set(SOLOUD_C_API_SOURCES + ${SOLOUD_C_API_SOURCE_DIR}/soloud_c.cpp ) - add_definitions(-DWITH_NULL) +source_group("C API" FILES ${SOLOUD_C_API_SOURCES}) +list(APPEND SOLOUD_SOURCES ${SOLOUD_C_API_SOURCES}) + +############################################ +#Backends +############################################ +set(SOLOUD_BACKENDS_SOURCE_DIR ${SOLOUD_SOURCE_PATH_DIR}/backend) +set(SOLOUD_BACKENDS_SOURCES) + +if(SOLOUD_ENABLE_BACKEND_NULL) + list(APPEND SOLOUD_BACKENDS_SOURCES ${SOLOUD_BACKENDS_SOURCE_DIR}/null/soloud_null.cpp) + apply_to_soloud_libraries(target_compile_definitions PUBLIC WITH_NULL=1) endif() -if (SOLOUD_BACKEND_SDL2) - find_package (SDL2 REQUIRED) - include_directories (${SDL2_INCLUDE_DIR}) - add_definitions (-DWITH_SDL2_STATIC) - - set (BACKENDS_SOURCES - ${BACKENDS_SOURCES} - ${BACKENDS_PATH}/sdl2_static/soloud_sdl2_static.cpp - ) - - set (LINK_LIBRARIES - ${LINK_LIBRARIES} - ${SDL2_LIBRARY} - ) +if(SOLOUD_ENABLE_BACKEND_SDL2) + list(APPEND SOLOUD_BACKENDS_SOURCES ${SOLOUD_BACKENDS_SOURCE_DIR}/sdl2_static/soloud_sdl2_static.cpp) + find_package (SDL2 REQUIRED) + apply_to_soloud_libraries(target_include_directories PUBLIC ${SDL2_INCLUDE_DIR}) + apply_to_soloud_libraries(target_link_libraries PUBLIC ${SDL2_LIBRARY}) + apply_to_soloud_libraries(target_compile_definitions PUBLIC WITH_SDL2_STATIC=1) endif() -if (SOLOUD_BACKEND_COREAUDIO) - if (NOT APPLE) - message (FATAL_ERROR "CoreAudio backend can be enabled only on Apple!") - endif () +if(SOLOUD_ENABLE_BACKEND_ALSA) + list(APPEND SOLOUD_BACKENDS_SOURCES ${SOLOUD_BACKENDS_SOURCE_DIR}/alsa/soloud_alsa.cpp) - add_definitions (-DWITH_COREAUDIO) - - set (BACKENDS_SOURCES - ${BACKENDS_SOURCES} - ${BACKENDS_PATH}/coreaudio/soloud_coreaudio.cpp - ) - - find_library (AUDIOTOOLBOX_FRAMEWORK AudioToolbox) - set (LINK_LIBRARIES - ${LINK_LIBRARIES} - ${AUDIOTOOLBOX_FRAMEWORK} - ) + find_package(ALSA REQUIRED) + apply_to_soloud_libraries(target_include_directories PUBLIC ${ALSA_INCLUDE_DIRS}) + apply_to_soloud_libraries(target_link_libraries PUBLIC ${ALSA_LIBRARIES}) + apply_to_soloud_libraries(target_compile_definitions PUBLIC WITH_ALSA=1) endif() +if(SOLOUD_ENABLE_BACKEND_PIPEWIRE) + list(APPEND SOLOUD_BACKENDS_SOURCES ${SOLOUD_BACKENDS_SOURCE_DIR}/pipewire/soloud_pipewire.cpp) -if (SOLOUD_BACKEND_OPENSLES) - add_definitions (-DWITH_OPENSLES) - - set (BACKENDS_SOURCES - ${BACKENDS_SOURCES} - ${BACKENDS_PATH}/opensles/soloud_opensles.cpp - ) - - find_library (OPENSLES_LIBRARY OpenSLES) - set (LINK_LIBRARIES - ${LINK_LIBRARIES} - ${OPENSLES_LIBRARY} - ) + find_package(PipeWire REQUIRED) + apply_to_soloud_libraries(target_link_libraries PUBLIC PipeWire::PipeWire) + apply_to_soloud_libraries(target_compile_definitions PUBLIC WITH_PIPEWIRE=1) endif() +if (SOLOUD_ENABLE_BACKEND_COREAUDIO) + if(NOT APPLE) + message(FATAL_ERROR "CoreAudio backend can be enabled only on Apple!") + endif() -if (SOLOUD_BACKEND_XAUDIO2) - add_definitions (-DWITH_XAUDIO2) + list(APPEND SOLOUD_BACKENDS_SOURCES ${SOLOUD_BACKENDS_SOURCE_DIR}/coreaudio/soloud_coreaudio.cpp) - set (BACKENDS_SOURCES - ${BACKENDS_SOURCES} - ${BACKENDS_PATH}/xaudio2/soloud_xaudio2.cpp - ) + find_library (AUDIOTOOLBOX_FRAMEWORK AudioToolbox) + apply_to_soloud_libraries(target_link_libraries PUBLIC ${AUDIOTOOLBOX_FRAMEWORK}) + apply_to_soloud_libraries(target_compile_definitions PUBLIC WITH_COREAUDIO=1) endif() -if (SOLOUD_BACKEND_WINMM) - add_definitions (-DWITH_WINMM) +if (SOLOUD_ENABLE_BACKEND_OPENSLES) + list(APPEND SOLOUD_BACKENDS_SOURCES ${SOLOUD_BACKENDS_SOURCE_DIR}/opensles/soloud_opensles.cpp) - set (BACKENDS_SOURCES - ${BACKENDS_SOURCES} - ${BACKENDS_PATH}/winmm/soloud_winmm.cpp - ) + find_library (OPENSLES_LIBRARY OpenSLES) + apply_to_soloud_libraries(target_link_libraries PUBLIC ${OPENSLES_LIBRARY}) + apply_to_soloud_libraries(target_compile_definitions PUBLIC WITH_OPENSLES=1) endif() -if (SOLOUD_BACKEND_WASAPI) - add_definitions (-DWITH_WASAPI) - - set (BACKENDS_SOURCES - ${BACKENDS_SOURCES} - ${BACKENDS_PATH}/wasapi/soloud_wasapi.cpp - ) +if (SOLOUD_ENABLE_BACKEND_XAUDIO2) + list(APPEND SOLOUD_BACKENDS_SOURCES ${SOLOUD_BACKENDS_SOURCE_DIR}/xaudio2/soloud_xaudio2.cpp) + apply_to_soloud_libraries(target_compile_definitions PUBLIC WITH_XAUDIO2=1) endif() -# Filters -set (FILTERS_PATH ${SOURCE_PATH}/filter) -set (FILTERS_SOURCES - ${FILTERS_PATH}/soloud_bassboostfilter.cpp - ${FILTERS_PATH}/soloud_biquadresonantfilter.cpp - ${FILTERS_PATH}/soloud_dcremovalfilter.cpp - ${FILTERS_PATH}/soloud_echofilter.cpp - ${FILTERS_PATH}/soloud_fftfilter.cpp - ${FILTERS_PATH}/soloud_flangerfilter.cpp - ${FILTERS_PATH}/soloud_lofifilter.cpp -) - - -# All together -source_group ("Includes" FILES ${TARGET_HEADERS}) -source_group ("Core" FILES ${CORE_SOURCES}) -source_group ("Audiosources" FILES ${AUDIOSOURCES_SOURCES}) -source_group ("Backends" FILES ${BACKENDS_SOURCES}) -source_group ("Filters" FILES ${FILTERS_SOURCES}) - -set (TARGET_SOURCES - ${CORE_SOURCES} - ${AUDIOSOURCES_SOURCES} - ${BACKENDS_SOURCES} - ${FILTERS_SOURCES} -) - -if (SOLOUD_DYNAMIC) - add_library(${TARGET_NAME} ${TARGET_SOURCES}) -endif () +if (SOLOUD_ENABLE_BACKEND_WINMM) + list(APPEND SOLOUD_BACKENDS_SOURCES ${SOLOUD_BACKENDS_SOURCE_DIR}/winmm/soloud_winmm.cpp) + apply_to_soloud_libraries(target_compile_definitions PUBLIC WITH_WINMM=1) +endif() -if (SOLOUD_STATIC) - add_library(${TARGET_NAME} STATIC ${TARGET_SOURCES}) +if (SOLOUD_ENABLE_BACKEND_WASAPI) + list(APPEND SOLOUD_BACKENDS_SOURCES ${SOLOUD_BACKENDS_SOURCE_DIR}/wasapi/soloud_wasapi.cpp) + apply_to_soloud_libraries(target_compile_definitions PUBLIC WITH_WASAPI=1) endif() -target_link_libraries (${TARGET_NAME} ${LINK_LIBRARIES}) +source_group ("Backends" FILES ${SOLOUD_BACKENDS_SOURCES}) +list(APPEND SOLOUD_SOURCES ${SOLOUD_BACKENDS_SOURCES}) -include (Install) -INSTALL(FILES ${TARGET_HEADERS} DESTINATION include/${TARGET_NAME}) +#Apply the source files +apply_to_soloud_libraries(target_sources PUBLIC ${SOLOUD_SOURCES}) +apply_to_soloud_libraries(target_include_directories PUBLIC ${SOLOUD_ROOT_DIRECTORY}/include) diff --git a/demos/common/soloud_demo_framework.cpp b/demos/common/soloud_demo_framework.cpp index 826dcd2f..7e9b5517 100644 --- a/demos/common/soloud_demo_framework.cpp +++ b/demos/common/soloud_demo_framework.cpp @@ -53,6 +53,9 @@ #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" +const int cgWindowWidth = 800; +const int cgWindowsHeight = 400; + int gPressed[256], gWasPressed[256]; int gMouseX = 0; int gMouseY = 0; @@ -550,7 +553,7 @@ void UpdateImGui() ImGuiIO& io = ImGui::GetIO(); // Setup resolution (every frame to accommodate for window resizing) - io.DisplaySize = ImVec2((float)800, (float)400); + io.DisplaySize = ImVec2((float)cgWindowWidth, (float)cgWindowsHeight); // Setup time step static double time = 0.0f; @@ -609,8 +612,8 @@ void DemoInit() "", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - 800, - 400, + cgWindowWidth, + cgWindowsHeight, flags); SDL_GLContext glcontext = SDL_GL_CreateContext(gSDLWindow); @@ -618,7 +621,7 @@ void DemoInit() SDL_GL_SetSwapInterval(1); - glViewport(0, 0, 800, 400); + glViewport(0, 0, cgWindowWidth, cgWindowsHeight); // set window title SDL_SetWindowTitle(gSDLWindow, "http://soloud-audio.com"); @@ -714,7 +717,7 @@ void DemoUpdateStart() } glClearColor(0.2f, 0.2f, 0.4f, 0); glClear(GL_COLOR_BUFFER_BIT); - DemoTexQuad(desktop_tex, 0, 0, 800, 400); + DemoTexQuad(desktop_tex, 0, 0, cgWindowWidth, cgWindowsHeight); UpdateImGui(); gMouseX = gUIState.mousex; diff --git a/include/soloud.h b/include/soloud.h index c759ee41..727c79fc 100644 --- a/include/soloud.h +++ b/include/soloud.h @@ -175,17 +175,18 @@ namespace SoLoud WINMM, XAUDIO2, WASAPI, - ALSA, + ALSA, OSS, OPENAL, COREAUDIO, OPENSLES, VITA_HOMEBREW, NULLDRIVER, - BACKEND_MAX, + PIPEWIRE, + BACKEND_MAX, }; - enum FLAGS + enum FLAGS { // Use round-off clipper CLIP_ROUNDOFF = 1, diff --git a/include/soloud_c.h b/include/soloud_c.h index c9b9f91b..01b374a2 100644 --- a/include/soloud_c.h +++ b/include/soloud_c.h @@ -52,7 +52,8 @@ enum SOLOUD_ENUMS SOLOUD_OPENSLES = 11, SOLOUD_VITA_HOMEBREW = 12, SOLOUD_NULLDRIVER = 13, - SOLOUD_BACKEND_MAX = 14, + SOLOUD_PIPEWIRE = 14, + SOLOUD_BACKEND_MAX = 15, SOLOUD_CLIP_ROUNDOFF = 1, SOLOUD_ENABLE_VISUALIZATION = 2, SOLOUD_LEFT_HANDED_3D = 4, diff --git a/include/soloud_internal.h b/include/soloud_internal.h index 7502c11a..ec049bfd 100644 --- a/include/soloud_internal.h +++ b/include/soloud_internal.h @@ -71,6 +71,9 @@ namespace SoLoud // ALSA back-end initialization call result alsa_init(SoLoud::Soloud *aSoloud, unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aSamplerate = 44100, unsigned int aBuffer = 2048, unsigned int aChannels = 2); + // PipeWire back-end initialization call + result pipewire_init(SoLoud::Soloud *aSoloud, unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aSamplerate = 44100, unsigned int aBuffer = 2048, unsigned int aChannels = 2); + // null driver back-end initialization call result null_init(SoLoud::Soloud *aSoloud, unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aSamplerate = 44100, unsigned int aBuffer = 2048, unsigned int aChannels = 2); @@ -118,4 +121,4 @@ namespace SoLoud h_++; \ } -#endif \ No newline at end of file +#endif diff --git a/src/backend/pipewire/soloud_pipewire.cpp b/src/backend/pipewire/soloud_pipewire.cpp new file mode 100644 index 00000000..7ecf03b5 --- /dev/null +++ b/src/backend/pipewire/soloud_pipewire.cpp @@ -0,0 +1,235 @@ +/* +SoLoud audio engine +Copyright (c) 2013-2015 Jari Komppa + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ +#include "soloud.h" +#if !defined(WITH_PIPEWIRE) + +namespace SoLoud +{ + result sdl2static_init(SoLoud::Soloud *aSoloud, unsigned int aFlags, unsigned int aSamplerate, unsigned int aBuffer) + { + return NOT_IMPLEMENTED; + } +} + +#else +#include "soloud_thread.h" + +#include "pipewire/pipewire.h" +#include + +namespace SoLoud +{ + class PipeWireBackendState + { + public: + PipeWireBackendState() + { + m_PipewireParameterPODWrapper = spa_pod_builder(); + m_PipewireParameterPODWrapper.data = m_PipewireParameterBuffer; + m_PipewireParameterPODWrapper.size = c_PipewireParameterBufferSize; + + m_PODParameters[0] = nullptr; + } + + ~PipeWireBackendState() + { + StopProcessing(); + } + + bool SetSoloudEngineInstance(Soloud* connectedEngine) + { + m_SoundLoadEngineInstance = connectedEngine; + return true; + } + + bool SetOutputStream(unsigned int newNumberOfChannels, unsigned int newSampleRate) + { + m_OutputAudioStreamInformation = SPA_AUDIO_INFO_RAW_INIT(); + m_OutputAudioStreamInformation.format = SPA_AUDIO_FORMAT_F32; + m_OutputAudioStreamInformation.channels = newNumberOfChannels; + m_OutputAudioStreamInformation.rate = newSampleRate; + return true; + } + + bool StartProcessing() + { + //Ensure that a previous stream is not already running + StopProcessing(); + m_PipewireLoop = pw_thread_loop_new("SoLoud Pipewire Thread", nullptr); + m_PipewirePlaybackProperties = pw_properties_new(PW_KEY_MEDIA_TYPE, "Audio", + PW_KEY_MEDIA_CATEGORY, "Playback", + PW_KEY_MEDIA_ROLE, "Game", + PW_KEY_MODULE_NAME, "Soloud", + nullptr); + + m_OutputAudioStream = pw_stream_new_simple(pw_thread_loop_get_loop(m_PipewireLoop), + "Soloud", + m_PipewirePlaybackProperties, + &cs_StreamSoloudData, + this); + + m_PODParameters[0] = spa_format_audio_raw_build(&m_PipewireParameterPODWrapper, + SPA_PARAM_EnumFormat, + &m_OutputAudioStreamInformation); + + int errorCode = pw_stream_connect(m_OutputAudioStream, + PW_DIRECTION_OUTPUT, + PW_ID_ANY, + static_cast(PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS | PW_STREAM_FLAG_RT_PROCESS), + m_PODParameters, + c_PODParametersSize); + + pw_thread_loop_start(m_PipewireLoop); + + return false; + } + + bool StopProcessing() + { + if(m_OutputAudioStream != nullptr) + { + pw_stream_destroy(m_OutputAudioStream); + m_OutputAudioStream = nullptr; + } + + if(m_PipewireLoop) + { + pw_thread_loop_stop(m_PipewireLoop); + m_PipewireLoop = nullptr; + } + + if(m_PipewirePlaybackProperties) + { + pw_properties_free(m_PipewirePlaybackProperties); + m_PipewirePlaybackProperties = nullptr; + } + + m_PODParameters[0] = nullptr; + + return true; + } + + bool clear() + { + m_SoundLoadEngineInstance = nullptr; + m_DesiredBufferSize = 0; + return true; + } + + bool SetDesiredBufferSize(unsigned int newDesiredBufferSize) + { + m_DesiredBufferSize = newDesiredBufferSize; + return true; + } + + const uint32_t& GetNumerOfPlaybackChannels() const + { + return m_OutputAudioStreamInformation.channels; + } + + static void PipewireMixSoloudData(void *userdata) + { + PipeWireBackendState* soloudPipewireState = reinterpret_cast(userdata); + + struct pw_buffer *pipewireBuffer; + int numberOfFrames, stride; + float* destinationBuffer; + + if ((pipewireBuffer = pw_stream_dequeue_buffer(soloudPipewireState->m_OutputAudioStream)) == NULL) + { + pw_log_warn("out of buffers: %m"); + return; + } + + if ((destinationBuffer = reinterpret_cast(pipewireBuffer->buffer->datas[0].data)) == NULL) + return; + + stride = sizeof(float) * soloudPipewireState->GetNumerOfPlaybackChannels(); + numberOfFrames = soloudPipewireState->m_DesiredBufferSize / stride; + + soloudPipewireState->m_SoundLoadEngineInstance->mix(destinationBuffer, numberOfFrames); + + pipewireBuffer->buffer->datas[0].chunk->offset = 0; + pipewireBuffer->buffer->datas[0].chunk->stride = stride; + pipewireBuffer->buffer->datas[0].chunk->size = numberOfFrames * stride; + + int output = pw_stream_queue_buffer(soloudPipewireState->m_OutputAudioStream, pipewireBuffer); + } + + constexpr static const struct pw_stream_events cs_StreamSoloudData ={ + .destroy = nullptr, + .state_changed = nullptr, + .control_info = nullptr, + .io_changed = nullptr, + .param_changed = nullptr, + .add_buffer = nullptr, + .remove_buffer = nullptr, + .process = PipewireMixSoloudData, + .drained = nullptr, + .command = nullptr, + .trigger_done = nullptr + }; + + protected: + static const size_t c_PipewireParameterBufferSize = 1024; + uint8_t m_PipewireParameterBuffer[c_PipewireParameterBufferSize]; + struct spa_pod_builder m_PipewireParameterPODWrapper; + struct pw_thread_loop *m_PipewireLoop{nullptr}; //Used to grab data to run + + struct pw_properties *m_PipewirePlaybackProperties{nullptr}; + + struct pw_stream *m_OutputAudioStream{nullptr}; + struct spa_audio_info_raw m_OutputAudioStreamInformation{}; + + static const unsigned int c_PODParametersSize = 1; + const struct spa_pod* m_PODParameters[c_PODParametersSize]; + + Soloud* m_SoundLoadEngineInstance{nullptr}; + unsigned int m_DesiredBufferSize{0}; + }; + + static PipeWireBackendState s_PipewireState; + + static void pipewire_init_deinit(SoLoud::Soloud *aSoloud) + { + s_PipewireState.StopProcessing(); + } + + result pipewire_init(Soloud *aSoloud, unsigned int aFlags, unsigned int aSamplerate, unsigned int aBuffer, unsigned int aChannels) + { + pw_init(nullptr, nullptr); //Initialize the pipewire api + s_PipewireState.SetSoloudEngineInstance(aSoloud); + s_PipewireState.SetDesiredBufferSize(aBuffer); + s_PipewireState.SetOutputStream(aChannels, aSamplerate); + + aSoloud->postinit(aSamplerate, aBuffer * aChannels, aFlags, aChannels); + aSoloud->mBackendCleanupFunc = pipewire_init_deinit; + aSoloud->mBackendString = "Pipewire"; + //aSoloud->mBackendData; + s_PipewireState.StartProcessing(); + + return SO_NO_ERROR; + } +} +#endif diff --git a/src/core/soloud.cpp b/src/core/soloud.cpp index 922409bc..fa114852 100644 --- a/src/core/soloud.cpp +++ b/src/core/soloud.cpp @@ -365,6 +365,26 @@ namespace SoLoud } #endif +#if defined(WITH_PIPEWIRE) + if (!inited && + (aBackend == Soloud::PIPEWIRE || + aBackend == Soloud::AUTO)) + { + if (aBufferSize == Soloud::AUTO) + buffersize = 2048; + + int ret = pipewire_init(this, aFlags, samplerate, buffersize, aChannels); + if (ret == 0) + { + inited = 1; + mBackendID = Soloud::PIPEWIRE; + } + + if (ret != 0 && aBackend != Soloud::AUTO) + return ret; + } +#endif + #if defined(WITH_ALSA) if (!inited && (aBackend == Soloud::ALSA ||