externals: Add option to use system SoundTouch (#6971)
This commit is contained in:
parent
d2d37411bc
commit
8aee625a14
5 changed files with 84 additions and 7 deletions
|
@ -86,6 +86,7 @@ option(USE_SYSTEM_SDL2 "Use the system SDL2 lib (instead of the bundled one)" OF
|
||||||
option(USE_SYSTEM_BOOST "Use the system Boost libs (instead of the bundled ones)" OFF)
|
option(USE_SYSTEM_BOOST "Use the system Boost libs (instead of the bundled ones)" OFF)
|
||||||
option(USE_SYSTEM_OPENSSL "Use the system OpenSSL libs (instead of the bundled LibreSSL)" OFF)
|
option(USE_SYSTEM_OPENSSL "Use the system OpenSSL libs (instead of the bundled LibreSSL)" OFF)
|
||||||
option(USE_SYSTEM_LIBUSB "Use the system libusb (instead of the bundled libusb)" OFF)
|
option(USE_SYSTEM_LIBUSB "Use the system libusb (instead of the bundled libusb)" OFF)
|
||||||
|
option(USE_SYSTEM_SOUNDTOUCH "Use the system SoundTouch (instead of the bundled one)" OFF)
|
||||||
|
|
||||||
if (CITRA_USE_PRECOMPILED_HEADERS)
|
if (CITRA_USE_PRECOMPILED_HEADERS)
|
||||||
message(STATUS "Using Precompiled Headers.")
|
message(STATUS "Using Precompiled Headers.")
|
||||||
|
@ -389,6 +390,14 @@ if (ENABLE_LIBUSB AND USE_SYSTEM_LIBUSB)
|
||||||
find_package(LibUSB)
|
find_package(LibUSB)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (USE_SYSTEM_SOUNDTOUCH)
|
||||||
|
include(FindPkgConfig)
|
||||||
|
find_package(SoundTouch REQUIRED)
|
||||||
|
add_library(SoundTouch INTERFACE)
|
||||||
|
target_link_libraries(SoundTouch INTERFACE "${SOUNDTOUCH_LIBRARIES}")
|
||||||
|
target_include_directories(SoundTouch INTERFACE "${SOUNDTOUCH_INCLUDE_DIRS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(dist/installer)
|
add_subdirectory(dist/installer)
|
||||||
|
|
||||||
|
|
3
externals/CMakeLists.txt
vendored
3
externals/CMakeLists.txt
vendored
|
@ -122,10 +122,13 @@ add_subdirectory(open_source_archives)
|
||||||
add_subdirectory(library-headers EXCLUDE_FROM_ALL)
|
add_subdirectory(library-headers EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
# SoundTouch
|
# SoundTouch
|
||||||
|
if(NOT USE_SYSTEM_SOUNDTOUCH)
|
||||||
set(INTEGER_SAMPLES ON CACHE BOOL "")
|
set(INTEGER_SAMPLES ON CACHE BOOL "")
|
||||||
set(SOUNDSTRETCH OFF CACHE BOOL "")
|
set(SOUNDSTRETCH OFF CACHE BOOL "")
|
||||||
set(SOUNDTOUCH_DLL OFF CACHE BOOL "")
|
set(SOUNDTOUCH_DLL OFF CACHE BOOL "")
|
||||||
add_subdirectory(soundtouch EXCLUDE_FROM_ALL)
|
add_subdirectory(soundtouch EXCLUDE_FROM_ALL)
|
||||||
|
target_compile_definitions(SoundTouch PUBLIC SOUNDTOUCH_INTEGER_SAMPLES)
|
||||||
|
endif()
|
||||||
|
|
||||||
# sirit
|
# sirit
|
||||||
add_subdirectory(sirit EXCLUDE_FROM_ALL)
|
add_subdirectory(sirit EXCLUDE_FROM_ALL)
|
||||||
|
|
27
externals/cmake-modules/FindSoundTouch.cmake
vendored
Normal file
27
externals/cmake-modules/FindSoundTouch.cmake
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
if(NOT SOUNDTOUCH_FOUND)
|
||||||
|
pkg_check_modules(SOUNDTOUCH_TMP soundtouch)
|
||||||
|
|
||||||
|
find_path(SOUNDTOUCH_INCLUDE_DIRS NAMES SoundTouch.h
|
||||||
|
PATHS
|
||||||
|
${SOUNDTOUCH_TMP_INCLUDE_DIRS}
|
||||||
|
/usr/include/soundtouch
|
||||||
|
/usr/include
|
||||||
|
/usr/local/include/soundtouch
|
||||||
|
/usr/local/include
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(SOUNDTOUCH_LIBRARIES NAMES SoundTouch
|
||||||
|
PATHS
|
||||||
|
${SOUNDTOUCH_TMP_LIBRARY_DIRS}
|
||||||
|
/usr/lib
|
||||||
|
/usr/local/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
if(SOUNDTOUCH_INCLUDE_DIRS AND SOUNDTOUCH_LIBRARIES)
|
||||||
|
set(SOUNDTOUCH_FOUND TRUE CACHE INTERNAL "SoundTouch found")
|
||||||
|
message(STATUS "Found SoundTouch: ${SOUNDTOUCH_INCLUDE_DIRS}, ${SOUNDTOUCH_LIBRARIES}")
|
||||||
|
else()
|
||||||
|
set(SOUNDTOUCH_FOUND FALSE CACHE INTERNAL "SoundTouch found")
|
||||||
|
message(STATUS "SoundTouch not found.")
|
||||||
|
endif()
|
||||||
|
endif()
|
|
@ -49,7 +49,6 @@ create_target_directory_groups(audio_core)
|
||||||
|
|
||||||
target_link_libraries(audio_core PUBLIC citra_common citra_core)
|
target_link_libraries(audio_core PUBLIC citra_common citra_core)
|
||||||
target_link_libraries(audio_core PRIVATE SoundTouch teakra)
|
target_link_libraries(audio_core PRIVATE SoundTouch teakra)
|
||||||
add_definitions(-DSOUNDTOUCH_INTEGER_SAMPLES)
|
|
||||||
|
|
||||||
if(ENABLE_MF)
|
if(ENABLE_MF)
|
||||||
target_sources(audio_core PRIVATE
|
target_sources(audio_core PRIVATE
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
#include <SoundTouch.h>
|
#include <SoundTouch.h>
|
||||||
#include "audio_core/audio_types.h"
|
#include "audio_core/audio_types.h"
|
||||||
#include "audio_core/time_stretch.h"
|
#include "audio_core/time_stretch.h"
|
||||||
|
@ -62,8 +65,44 @@ std::size_t TimeStretcher::Process(const s16* in, std::size_t num_in, s16* out,
|
||||||
LOG_TRACE(Audio, "{:5}/{:5} ratio:{:0.6f} backlog:{:0.6f}", num_in, num_out, stretch_ratio,
|
LOG_TRACE(Audio, "{:5}/{:5} ratio:{:0.6f} backlog:{:0.6f}", num_in, num_out, stretch_ratio,
|
||||||
backlog_fullness);
|
backlog_fullness);
|
||||||
|
|
||||||
sound_touch->putSamples(in, static_cast<u32>(num_in));
|
if constexpr (std::is_floating_point<soundtouch::SAMPLETYPE>()) {
|
||||||
return sound_touch->receiveSamples(out, static_cast<u32>(num_out));
|
// The SoundTouch library on most systems expects float samples
|
||||||
|
// use this vector to store input if soundtouch::SAMPLETYPE is a float
|
||||||
|
std::vector<soundtouch::SAMPLETYPE> float_in(2 * num_in);
|
||||||
|
std::vector<soundtouch::SAMPLETYPE> float_out(2 * num_out);
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < (2 * num_in); i++) {
|
||||||
|
// Conventional integer PCM uses a range of -32768 to 32767,
|
||||||
|
// but float samples use -1 to 1
|
||||||
|
// As a result we need to scale sample values during conversion
|
||||||
|
const float temp = static_cast<float>(in[i]) / std::numeric_limits<s16>::max();
|
||||||
|
float_in[i] = static_cast<soundtouch::SAMPLETYPE>(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
sound_touch->putSamples(float_in.data(), static_cast<u32>(num_in));
|
||||||
|
|
||||||
|
const std::size_t samples_received =
|
||||||
|
sound_touch->receiveSamples(float_out.data(), static_cast<u32>(num_out));
|
||||||
|
|
||||||
|
// Converting output samples back to shorts so we can use them
|
||||||
|
for (std::size_t i = 0; i < (2 * num_out); i++) {
|
||||||
|
const s16 temp = static_cast<s16>(float_out[i] * std::numeric_limits<s16>::max());
|
||||||
|
out[i] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return samples_received;
|
||||||
|
} else if (std::is_same<soundtouch::SAMPLETYPE, s16>()) {
|
||||||
|
// Use reinterpret_cast to workaround compile error when SAMPLETYPE is float.
|
||||||
|
sound_touch->putSamples(reinterpret_cast<const soundtouch::SAMPLETYPE*>(in),
|
||||||
|
static_cast<u32>(num_in));
|
||||||
|
return sound_touch->receiveSamples(reinterpret_cast<soundtouch::SAMPLETYPE*>(out),
|
||||||
|
static_cast<u32>(num_out));
|
||||||
|
} else {
|
||||||
|
static_assert(std::is_floating_point<soundtouch::SAMPLETYPE>() ||
|
||||||
|
std::is_same<soundtouch::SAMPLETYPE, s16>());
|
||||||
|
UNREACHABLE_MSG("Invalid SAMPLETYPE {}", typeid(soundtouch::SAMPLETYPE).name());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimeStretcher::Clear() {
|
void TimeStretcher::Clear() {
|
||||||
|
|
Loading…
Reference in a new issue