diff --git a/CMakeModules/DuckStationDependencies.cmake b/CMakeModules/DuckStationDependencies.cmake index 44aca88a0..ec65a1d39 100644 --- a/CMakeModules/DuckStationDependencies.cmake +++ b/CMakeModules/DuckStationDependencies.cmake @@ -18,6 +18,7 @@ find_package(JPEG REQUIRED) # No version because flatpak uses libjpeg-turbo. find_package(Freetype 2.11.1 REQUIRED) find_package(cpuinfo REQUIRED) find_package(DiscordRPC 3.4.0 REQUIRED) +find_package(SoundTouch 2.3.3 REQUIRED) if(NOT WIN32) find_package(CURL REQUIRED) diff --git a/dep/CMakeLists.txt b/dep/CMakeLists.txt index 4e9e80952..816f4a6ad 100644 --- a/dep/CMakeLists.txt +++ b/dep/CMakeLists.txt @@ -14,8 +14,6 @@ disable_compiler_warnings_for_target(imgui) add_subdirectory(simpleini EXCLUDE_FROM_ALL) disable_compiler_warnings_for_target(simpleini) add_subdirectory(vulkan EXCLUDE_FROM_ALL) -add_subdirectory(soundtouch EXCLUDE_FROM_ALL) -disable_compiler_warnings_for_target(soundtouch) add_subdirectory(googletest EXCLUDE_FROM_ALL) add_subdirectory(fast_float EXCLUDE_FROM_ALL) add_subdirectory(reshadefx EXCLUDE_FROM_ALL) diff --git a/scripts/deps/build-dependencies-linux.sh b/scripts/deps/build-dependencies-linux.sh index adff9e29f..b8e4c6c46 100755 --- a/scripts/deps/build-dependencies-linux.sh +++ b/scripts/deps/build-dependencies-linux.sh @@ -25,6 +25,7 @@ ZSTD=1.5.6 CPUINFO=7524ad504fdcfcf75a18a133da6abd75c5d48053 DISCORD_RPC=842c15192041f8e71c512851834f4dadb1a554fb SHADERC=feb2460bf3a504d67011246edeb810c45ea58826 +SOUNDTOUCH=463ade388f3a51da078dc9ed062bf28e4ba29da7 SPIRV_CROSS=vulkan-sdk-1.3.290.0 mkdir -p deps-build @@ -46,6 +47,7 @@ a2a057e1dd644bd44abb9990fecc194b2e25c2e0f39e81aa9fee4c1e5e2a8a5b qtwayland-ever e1351218d270db49c3dddcba04fb2153b09731ea3fa6830e423f5952f44585be cpuinfo-$CPUINFO.tar.gz acb111ebdb4f1459899b9c594be81ed284de23ac0f5376e5963aad16df98584f discord-rpc-$DISCORD_RPC.tar.gz 5a7f86eba3c6301bb573def825977c31aa3d5fc5500f213c123498707fdbd378 shaderc-$SHADERC.tar.gz +fe45c2af99f6102d2704277d392c1c83b55180a70bfd17fb888cc84a54b70573 soundtouch-$SOUNDTOUCH.tar.gz EOF curl -C - -L \ @@ -63,7 +65,8 @@ curl -C - -L \ -O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtwayland-everywhere-src-$QT.tar.xz" \ -o "cpuinfo-$CPUINFO.tar.gz" "https://github.com/stenzek/cpuinfo/archive/$CPUINFO.tar.gz" \ -o "discord-rpc-$DISCORD_RPC.tar.gz" "https://github.com/stenzek/discord-rpc/archive/$DISCORD_RPC.tar.gz" \ - -o "shaderc-$SHADERC.tar.gz" "https://github.com/stenzek/shaderc/archive/$SHADERC.tar.gz" + -o "shaderc-$SHADERC.tar.gz" "https://github.com/stenzek/shaderc/archive/$SHADERC.tar.gz" \ + -o "soundtouch-$SOUNDTOUCH.tar.gz" "https://github.com/stenzek/soundtouch/archive/$SOUNDTOUCH.tar.gz" shasum -a 256 --check SHASUMS @@ -261,6 +264,15 @@ cmake --build build --parallel ninja -C build install cd .. +echo "Building soundtouch..." +rm -fr "soundtouch-$SOUNDTOUCH" +tar xf "soundtouch-$SOUNDTOUCH.tar.gz" +cd "soundtouch-$SOUNDTOUCH" +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -B build -G Ninja +cmake --build build --parallel +ninja -C build install +cd .. + echo "Cleaning up..." cd .. rm -fr deps-build diff --git a/scripts/deps/build-dependencies-mac.sh b/scripts/deps/build-dependencies-mac.sh index a0439a238..92408436e 100755 --- a/scripts/deps/build-dependencies-mac.sh +++ b/scripts/deps/build-dependencies-mac.sh @@ -47,6 +47,7 @@ QT=6.7.2 CPUINFO=7524ad504fdcfcf75a18a133da6abd75c5d48053 DISCORD_RPC=842c15192041f8e71c512851834f4dadb1a554fb SHADERC=feb2460bf3a504d67011246edeb810c45ea58826 +SOUNDTOUCH=463ade388f3a51da078dc9ed062bf28e4ba29da7 SPIRV_CROSS=vulkan-sdk-1.3.290.0 mkdir -p deps-build @@ -84,7 +85,7 @@ fb0d1286a35be3583fee34aeb5843c94719e07193bdf1d4d8b0dc14009caef01 qtsvg-everywhe e1351218d270db49c3dddcba04fb2153b09731ea3fa6830e423f5952f44585be cpuinfo-$CPUINFO.tar.gz acb111ebdb4f1459899b9c594be81ed284de23ac0f5376e5963aad16df98584f discord-rpc-$DISCORD_RPC.tar.gz 5a7f86eba3c6301bb573def825977c31aa3d5fc5500f213c123498707fdbd378 shaderc-$SHADERC.tar.gz - +fe45c2af99f6102d2704277d392c1c83b55180a70bfd17fb888cc84a54b70573 soundtouch-$SOUNDTOUCH.tar.gz EOF curl -L \ @@ -103,7 +104,8 @@ curl -L \ -O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \ -o "cpuinfo-$CPUINFO.tar.gz" "https://github.com/stenzek/cpuinfo/archive/$CPUINFO.tar.gz" \ -o "discord-rpc-$DISCORD_RPC.tar.gz" "https://github.com/stenzek/discord-rpc/archive/$DISCORD_RPC.tar.gz" \ - -o "shaderc-$SHADERC.tar.gz" "https://github.com/stenzek/shaderc/archive/$SHADERC.tar.gz" + -o "shaderc-$SHADERC.tar.gz" "https://github.com/stenzek/shaderc/archive/$SHADERC.tar.gz" \ + -o "soundtouch-$SOUNDTOUCH.tar.gz" "https://github.com/stenzek/soundtouch/archive/$SOUNDTOUCH.tar.gz" shasum -a 256 --check SHASUMS @@ -347,6 +349,15 @@ cmake --build build --parallel cmake --install build cd .. +echo "Building soundtouch..." +rm -fr "soundtouch-$SOUNDTOUCH" +tar xf "soundtouch-$SOUNDTOUCH.tar.gz" +cd "soundtouch-$SOUNDTOUCH" +cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -B build +cmake --build build --parallel +cmake --install build +cd .. + echo "Cleaning up..." cd .. rm -rf deps-build diff --git a/scripts/deps/build-dependencies-windows-arm64.bat b/scripts/deps/build-dependencies-windows-arm64.bat index 35e694ae0..ecfc931d0 100644 --- a/scripts/deps/build-dependencies-windows-arm64.bat +++ b/scripts/deps/build-dependencies-windows-arm64.bat @@ -57,6 +57,7 @@ set ZSTD=1.5.6 set CPUINFO=7524ad504fdcfcf75a18a133da6abd75c5d48053 set DISCORD_RPC=842c15192041f8e71c512851834f4dadb1a554fb set SHADERC=feb2460bf3a504d67011246edeb810c45ea58826 +set SOUNDTOUCH=463ade388f3a51da078dc9ed062bf28e4ba29da7 set SPIRV_CROSS=vulkan-sdk-1.3.290.0 call :downloadfile "freetype-%FREETYPE%.tar.gz" https://download.savannah.gnu.org/releases/freetype/freetype-%FREETYPE%.tar.gz 1ac27e16c134a7f2ccea177faba19801131116fd682efc1f5737037c5db224b5 || goto error @@ -77,6 +78,7 @@ call :downloadfile "zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" https:/ call :downloadfile "cpuinfo-%CPUINFO%.zip" "https://github.com/pytorch/cpuinfo/archive/%CPUINFO%.zip" 13146ae7983d767a678dd01b0d6af591e77cec82babd41264b9164ab808d7d41 || goto error call :downloadfile "discord-rpc-%DISCORD_RPC%.zip" "https://github.com/stenzek/discord-rpc/archive/%DISCORD_RPC%.zip" 2a32201439fc2ddfc9c0ea4f4f7cfce40706983b9abac22cdba4ce750bcb55a1 || goto error call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/stenzek/shaderc/archive/%SHADERC%.zip" a50687a3903328976c3a49f6ba6326196f7713660048957eb033408630af70b1 || goto error +call :downloadfile "soundtouch-%SOUNDTOUCH%.zip" "https://github.com/stenzek/soundtouch/archive/%SOUNDTOUCH%.zip" 107a1941181a69abe28018b9ad26fc0218625758ac193bc979abc9e26b7c0c3a || goto error if not exist SPIRV-Cross\ ( git clone https://github.com/KhronosGroup/SPIRV-Cross/ -b %SPIRV_CROSS% --depth 1 || goto error @@ -273,6 +275,16 @@ cmake --build build --parallel || goto error ninja -C build install || goto error cd .. || goto error +rem This currently isn't using clang-cl. It probably should, might be losing a little speed. +echo Building soundtouch... +rmdir /S /Q "soundtouch-%SOUNDTOUCH%" +%SEVENZIP% x "soundtouch-%SOUNDTOUCH%.zip" || goto error +cd "soundtouch-%SOUNDTOUCH%" || goto error +cmake %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -B build -G Ninja || goto error +cmake --build build --parallel || goto error +ninja -C build install || goto error +cd .. || goto error + echo Cleaning up... cd .. rd /S /Q deps-build diff --git a/scripts/deps/build-dependencies-windows-x64.bat b/scripts/deps/build-dependencies-windows-x64.bat index 523a2b6e3..7c0ab8c7f 100644 --- a/scripts/deps/build-dependencies-windows-x64.bat +++ b/scripts/deps/build-dependencies-windows-x64.bat @@ -55,6 +55,7 @@ set ZSTD=1.5.6 set CPUINFO=7524ad504fdcfcf75a18a133da6abd75c5d48053 set DISCORD_RPC=842c15192041f8e71c512851834f4dadb1a554fb set SHADERC=feb2460bf3a504d67011246edeb810c45ea58826 +set SOUNDTOUCH=463ade388f3a51da078dc9ed062bf28e4ba29da7 set SPIRV_CROSS=vulkan-sdk-1.3.290.0 call :downloadfile "freetype-%FREETYPE%.tar.gz" https://download.savannah.gnu.org/releases/freetype/freetype-%FREETYPE%.tar.gz 1ac27e16c134a7f2ccea177faba19801131116fd682efc1f5737037c5db224b5 || goto error @@ -75,6 +76,7 @@ call :downloadfile "zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" https:/ call :downloadfile "cpuinfo-%CPUINFO%.zip" "https://github.com/pytorch/cpuinfo/archive/%CPUINFO%.zip" 13146ae7983d767a678dd01b0d6af591e77cec82babd41264b9164ab808d7d41 || goto error call :downloadfile "discord-rpc-%DISCORD_RPC%.zip" "https://github.com/stenzek/discord-rpc/archive/%DISCORD_RPC%.zip" 2a32201439fc2ddfc9c0ea4f4f7cfce40706983b9abac22cdba4ce750bcb55a1 || goto error call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/stenzek/shaderc/archive/%SHADERC%.zip" a50687a3903328976c3a49f6ba6326196f7713660048957eb033408630af70b1 || goto error +call :downloadfile "soundtouch-%SOUNDTOUCH%.zip" "https://github.com/stenzek/soundtouch/archive/%SOUNDTOUCH%.zip" 107a1941181a69abe28018b9ad26fc0218625758ac193bc979abc9e26b7c0c3a || goto error if not exist SPIRV-Cross\ ( git clone https://github.com/KhronosGroup/SPIRV-Cross/ -b %SPIRV_CROSS% --depth 1 || goto error @@ -270,6 +272,15 @@ cmake --build build --parallel || goto error ninja -C build install || goto error cd .. || goto error +echo Building soundtouch... +rmdir /S /Q "soundtouch-%SOUNDTOUCH%" +%SEVENZIP% x "soundtouch-%SOUNDTOUCH%.zip" || goto error +cd "soundtouch-%SOUNDTOUCH%" || goto error +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -B build -G Ninja || goto error +cmake --build build --parallel || goto error +ninja -C build install || goto error +cd .. || goto error + echo Cleaning up... cd .. rd /S /Q deps-build diff --git a/scripts/flatpak/modules/26-soundtouch.json b/scripts/flatpak/modules/26-soundtouch.json new file mode 100644 index 000000000..279e85cff --- /dev/null +++ b/scripts/flatpak/modules/26-soundtouch.json @@ -0,0 +1,28 @@ +{ + "name": "soundtouch", + "buildsystem": "cmake-ninja", + "builddir": true, + "config-opts": [ + "-DCMAKE_BUILD_TYPE=Release", + "-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON" + ], + "build-options": { + "strip": true + }, + "sources": [ + { + "type": "git", + "url": "https://github.com/stenzek/soundtouch.git", + "commit": "463ade388f3a51da078dc9ed062bf28e4ba29da7" + } + ], + "cleanup": [ + "/bin", + "/include", + "/lib/*.a", + "/lib/*.la", + "/lib/cmake", + "/lib/pkgconfig", + "/share" + ] +} diff --git a/scripts/flatpak/org.duckstation.DuckStation.json b/scripts/flatpak/org.duckstation.DuckStation.json index bc35420d4..3a69df210 100644 --- a/scripts/flatpak/org.duckstation.DuckStation.json +++ b/scripts/flatpak/org.duckstation.DuckStation.json @@ -24,6 +24,7 @@ "modules/23-spirv-cross.json", "modules/24-cpuinfo.json", "modules/25-discord-rpc.json", + "modules/26-soundtouch.json", { "name": "duckstation", "buildsystem": "cmake-ninja", diff --git a/src/duckstation-qt/CMakeLists.txt b/src/duckstation-qt/CMakeLists.txt index 83577213e..002f3e3fd 100644 --- a/src/duckstation-qt/CMakeLists.txt +++ b/src/duckstation-qt/CMakeLists.txt @@ -208,7 +208,7 @@ if(WIN32) #set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/translations") set(DEPS_TO_COPY cpuinfo.dll discord-rpc.dll freetype.dll harfbuzz.dll libjpeg.dll libpng16.dll libsharpyuv.dll libwebp.dll - SDL2.dll shaderc_shared.dll spirv-cross-c-shared.dll zlib1.dll zstd.dll) + SDL2.dll shaderc_shared.dll soundtouch.dll spirv-cross-c-shared.dll zlib1.dll zstd.dll) foreach(DEP ${DEPS_TO_COPY}) list(APPEND DEP_BINS "${CMAKE_PREFIX_PATH}/bin/${DEP}") endforeach() diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index b2e993697..5565fbfbb 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -73,7 +73,7 @@ target_precompile_headers(util PRIVATE "pch.h") target_include_directories(util PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..") target_include_directories(util PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..") target_link_libraries(util PUBLIC common simpleini imgui) -target_link_libraries(util PRIVATE libchdr JPEG::JPEG PNG::PNG WebP::libwebp ZLIB::ZLIB soundtouch xxhash Zstd::Zstd reshadefx) +target_link_libraries(util PRIVATE libchdr JPEG::JPEG PNG::PNG WebP::libwebp ZLIB::ZLIB SoundTouch::SoundTouchDLL xxhash Zstd::Zstd reshadefx) if(ENABLE_X11) target_compile_definitions(util PRIVATE "-DENABLE_X11=1") diff --git a/src/util/audio_stream.cpp b/src/util/audio_stream.cpp index cb2e56ce5..fb3639696 100644 --- a/src/util/audio_stream.cpp +++ b/src/util/audio_stream.cpp @@ -13,7 +13,8 @@ #include "common/small_string.h" #include "common/timer.h" -#include "SoundTouch.h" +#include "soundtouch/SoundTouch.h" +#include "soundtouch/SoundTouchDLL.h" #ifndef __ANDROID__ #include "freesurround_decoder.h" @@ -505,9 +506,9 @@ void AudioStream::EmptyBuffer() if (IsStretchEnabled()) { - m_soundtouch->clear(); + soundtouch_clear(m_soundtouch); if (m_parameters.stretch_mode == AudioStretchMode::TimeStretch) - m_soundtouch->setTempo(m_nominal_rate); + soundtouch_setTempo(m_soundtouch, m_nominal_rate); } m_wpos.store(m_rpos.load(std::memory_order_acquire), std::memory_order_release); @@ -517,9 +518,9 @@ void AudioStream::SetNominalRate(float tempo) { m_nominal_rate = tempo; if (m_parameters.stretch_mode == AudioStretchMode::Resample) - m_soundtouch->setRate(tempo); + soundtouch_setRate(m_soundtouch, tempo); else if (m_parameters.stretch_mode == AudioStretchMode::TimeStretch && m_stretch_inactive) - m_soundtouch->setTempo(tempo); + soundtouch_setTempo(m_soundtouch, tempo); } void AudioStream::SetStretchMode(AudioStretchMode mode) @@ -703,21 +704,21 @@ void AudioStream::StretchAllocate() if (m_parameters.stretch_mode == AudioStretchMode::Off) return; - m_soundtouch = std::make_unique(); - m_soundtouch->setSampleRate(m_sample_rate); - m_soundtouch->setChannels(m_internal_channels); + m_soundtouch = soundtouch_createInstance(); + soundtouch_setSampleRate(m_soundtouch, m_sample_rate); + soundtouch_setChannels(m_soundtouch, m_internal_channels); - m_soundtouch->setSetting(SETTING_USE_QUICKSEEK, m_parameters.stretch_use_quickseek); - m_soundtouch->setSetting(SETTING_USE_AA_FILTER, m_parameters.stretch_use_aa_filter); + soundtouch_setSetting(m_soundtouch, SETTING_USE_QUICKSEEK, m_parameters.stretch_use_quickseek); + soundtouch_setSetting(m_soundtouch, SETTING_USE_AA_FILTER, m_parameters.stretch_use_aa_filter); - m_soundtouch->setSetting(SETTING_SEQUENCE_MS, m_parameters.stretch_sequence_length_ms); - m_soundtouch->setSetting(SETTING_SEEKWINDOW_MS, m_parameters.stretch_seekwindow_ms); - m_soundtouch->setSetting(SETTING_OVERLAP_MS, m_parameters.stretch_overlap_ms); + soundtouch_setSetting(m_soundtouch, SETTING_SEQUENCE_MS, m_parameters.stretch_sequence_length_ms); + soundtouch_setSetting(m_soundtouch, SETTING_SEEKWINDOW_MS, m_parameters.stretch_seekwindow_ms); + soundtouch_setSetting(m_soundtouch, SETTING_OVERLAP_MS, m_parameters.stretch_overlap_ms); if (m_parameters.stretch_mode == AudioStretchMode::Resample) - m_soundtouch->setRate(m_nominal_rate); + soundtouch_setRate(m_soundtouch, m_nominal_rate); else - m_soundtouch->setTempo(m_nominal_rate); + soundtouch_setTempo(m_soundtouch, m_nominal_rate); m_stretch_reset = STRETCH_RESET_THRESHOLD; m_stretch_inactive = false; @@ -731,17 +732,21 @@ void AudioStream::StretchAllocate() void AudioStream::StretchDestroy() { - m_soundtouch.reset(); + if (m_soundtouch) + { + soundtouch_destroyInstance(m_soundtouch); + m_soundtouch = nullptr; + } } void AudioStream::StretchWriteBlock(const float* block) { if (IsStretchEnabled()) { - m_soundtouch->putSamples(block, CHUNK_SIZE); + soundtouch_putSamples(m_soundtouch, block, CHUNK_SIZE); u32 tempProgress; - while (tempProgress = m_soundtouch->receiveSamples(m_float_buffer.get(), CHUNK_SIZE), tempProgress != 0) + while (tempProgress = soundtouch_receiveSamples(m_soundtouch, m_float_buffer.get(), CHUNK_SIZE), tempProgress != 0) { FloatChunkToS16(m_staging_buffer.get(), m_float_buffer.get(), tempProgress * m_internal_channels); InternalWriteFrames(m_staging_buffer.get(), tempProgress); @@ -865,7 +870,7 @@ void AudioStream::UpdateStretchTempo() iterations++; } - m_soundtouch->setTempo(tempo); + soundtouch_setTempo(m_soundtouch, tempo); if (m_stretch_reset >= STRETCH_RESET_THRESHOLD) m_stretch_reset = 0; diff --git a/src/util/audio_stream.h b/src/util/audio_stream.h index 0d78c94fd..05297e083 100644 --- a/src/util/audio_stream.h +++ b/src/util/audio_stream.h @@ -279,7 +279,7 @@ private: std::atomic m_rpos{0}; std::atomic m_wpos{0}; - std::unique_ptr m_soundtouch; + void* m_soundtouch = nullptr; u32 m_target_buffer_size = 0; u32 m_stretch_reset = STRETCH_RESET_THRESHOLD; diff --git a/src/util/util.props b/src/util/util.props index 486fd31e3..4d3ae005f 100644 --- a/src/util/util.props +++ b/src/util/util.props @@ -27,7 +27,7 @@ %(AdditionalIncludeDirectories);$(DepsIncludeDir)SDL2 - %(AdditionalDependencies);cpuinfo.lib;freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;SDL2.lib;zlib.lib;zstd.lib + %(AdditionalDependencies);cpuinfo.lib;freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;SDL2.lib;soundtouch.lib;zlib.lib;zstd.lib @@ -41,6 +41,7 @@ +