mirror of
https://github.com/azahar-emu/soundtouch
synced 2025-11-07 15:40:04 +01:00
Compare commits
No commits in common. "master" and "2.3.3" have entirely different histories.
@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
project(SoundTouch VERSION 2.3.3 LANGUAGES CXX)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
@ -13,8 +13,7 @@ else()
|
||||
if(EMSCRIPTEN)
|
||||
list(APPEND COMPILE_OPTIONS -O3)
|
||||
else()
|
||||
# Apply -ffast-math to allow compiler autovectorization generate effective SIMD code for arm compilation
|
||||
list(APPEND COMPILE_OPTIONS -O3 -ffast-math)
|
||||
list(APPEND COMPILE_OPTIONS -Ofast)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -97,7 +96,6 @@ install(
|
||||
include/soundtouch_config.h
|
||||
DESTINATION
|
||||
"${CMAKE_INSTALL_INCLUDEDIR}/soundtouch"
|
||||
COMPONENT SoundTouch
|
||||
)
|
||||
|
||||
install(TARGETS SoundTouch
|
||||
@ -106,7 +104,6 @@ install(TARGETS SoundTouch
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
COMPONENT SoundTouch
|
||||
)
|
||||
|
||||
#######################
|
||||
@ -129,7 +126,6 @@ if(SOUNDSTRETCH)
|
||||
|
||||
install(TARGETS soundstretch
|
||||
DESTINATION bin
|
||||
COMPONENT soundstretch
|
||||
)
|
||||
endif()
|
||||
|
||||
@ -148,8 +144,8 @@ if(SOUNDTOUCH_DLL)
|
||||
target_compile_definitions(SoundTouchDLL PRIVATE DLL_EXPORTS)
|
||||
target_include_directories(SoundTouchDLL PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
|
||||
target_link_libraries(SoundTouchDLL PRIVATE SoundTouch)
|
||||
install(FILES source/SoundTouchDLL/SoundTouchDLL.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/soundtouch" COMPONENT SoundTouchDLL)
|
||||
install(TARGETS SoundTouchDLL EXPORT SoundTouchTargets COMPONENT SoundTouchDLL)
|
||||
install(FILES source/SoundTouchDLL/SoundTouchDLL.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/soundtouch")
|
||||
install(TARGETS SoundTouchDLL EXPORT SoundTouchTargets)
|
||||
endif()
|
||||
|
||||
########################
|
||||
@ -161,7 +157,7 @@ set(libdir "\${prefix}/${CMAKE_INSTALL_LIBDIR}")
|
||||
set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
set(VERSION "${CMAKE_PROJECT_VERSION}")
|
||||
configure_file(soundtouch.pc.in "${CMAKE_CURRENT_BINARY_DIR}/soundtouch.pc" @ONLY)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/soundtouch.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" COMPONENT SoundTouch)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/soundtouch.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
|
||||
# CMake config
|
||||
include(CMakePackageConfigHelpers)
|
||||
@ -171,7 +167,6 @@ install(
|
||||
FILE SoundTouchTargets.cmake
|
||||
NAMESPACE SoundTouch::
|
||||
DESTINATION "${SOUNDTOUCH_INSTALL_CMAKEDIR}"
|
||||
COMPONENT SoundTouch
|
||||
)
|
||||
configure_package_config_file(SoundTouchConfig.cmake.in
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/SoundTouchConfig.cmake"
|
||||
@ -187,5 +182,4 @@ install(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/SoundTouchConfig.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/SoundTouchConfigVersion.cmake"
|
||||
DESTINATION "${SOUNDTOUCH_INSTALL_CMAKEDIR}"
|
||||
COMPONENT SoundTouch
|
||||
)
|
||||
|
||||
@ -205,7 +205,7 @@
|
||||
separate mono channels, this isn't recommended because processing the
|
||||
channels separately would result in losing the phase coherency between
|
||||
the channels, which consequently would ruin the stereo effect.</p>
|
||||
<p>Sample rates between 8000-48000Hz are supported.</p>
|
||||
<p>Sample rates between 8000-48000H are supported.</p>
|
||||
<h3>3.2. Processing latency</h3>
|
||||
<p>The processing and latency constraints of the SoundTouch library are:</p>
|
||||
<ul>
|
||||
|
||||
@ -31,8 +31,9 @@ AC_DISABLE_STATIC dnl This makes libtool only build shared libs
|
||||
|
||||
AC_LANG(C++)
|
||||
|
||||
# Compiler flags. Apply -ffast-math to allow compiler autovectorization generate effective SIMD code for arm compilation
|
||||
CXXFLAGS="${CXXFLAGS} -O3 -ffast-math -Wall -Wextra -Wzero-as-null-pointer-constant -Wno-unknown-pragmas"
|
||||
# Compiler flags. Apply -Ofast (implies -O3 -ffast-math) to allow gcc autovectorization
|
||||
# generate effective SIMD code.
|
||||
CXXFLAGS="${CXXFLAGS} -Ofast -Wall -Wextra -Wzero-as-null-pointer-constant -Wno-unknown-pragmas"
|
||||
|
||||
# Set AR_FLAGS to avoid build warning "ar: `u' modifier ignored since `D' is the default (see `U')"
|
||||
AR_FLAGS='cr'
|
||||
|
||||
@ -56,9 +56,8 @@ typedef unsigned long ulong;
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
/// Max allowed number of channels. This is not a hard limit but to have some
|
||||
/// maximum value for argument sanity checks -- can be increased if necessary
|
||||
#define SOUNDTOUCH_MAX_CHANNELS 32
|
||||
/// Max allowed number of channels
|
||||
#define SOUNDTOUCH_MAX_CHANNELS 16
|
||||
|
||||
/// Activate these undef's to overrule the possible sampletype
|
||||
/// setting inherited from some other header file:
|
||||
|
||||
@ -199,7 +199,7 @@ void RunParameters::throwLicense() const
|
||||
ST_THROW_RT_ERROR(licenseText);
|
||||
}
|
||||
|
||||
double RunParameters::parseSwitchValue(const STRING& str) const
|
||||
float RunParameters::parseSwitchValue(const STRING& str) const
|
||||
{
|
||||
int pos;
|
||||
|
||||
@ -211,7 +211,7 @@ double RunParameters::parseSwitchValue(const STRING& str) const
|
||||
}
|
||||
|
||||
// Read numerical parameter value after '='
|
||||
return stof(str.substr(pos + 1).c_str());
|
||||
return (float)stof(str.substr(pos + 1).c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -48,17 +48,17 @@ private:
|
||||
void throwLicense() const;
|
||||
void parseSwitchParam(const STRING& str);
|
||||
void checkLimits();
|
||||
double parseSwitchValue(const STRING& tr) const;
|
||||
float parseSwitchValue(const STRING& tr) const;
|
||||
|
||||
public:
|
||||
STRING inFileName;
|
||||
STRING outFileName;
|
||||
double tempoDelta{ 0 };
|
||||
double pitchDelta{ 0 };
|
||||
double rateDelta{ 0 };
|
||||
float tempoDelta{ 0 };
|
||||
float pitchDelta{ 0 };
|
||||
float rateDelta{ 0 };
|
||||
int quick{ 0 };
|
||||
int noAntiAlias{ 0 };
|
||||
double goalBPM{ 0 };
|
||||
float goalBPM{ 0 };
|
||||
bool detectBPM{ false };
|
||||
bool speech{ false };
|
||||
|
||||
|
||||
@ -145,9 +145,9 @@ static void setup(SoundTouch& soundTouch, const WavInFile& inFile, const RunPara
|
||||
#endif
|
||||
// print processing information only if outFileName given i.e. some processing will happen
|
||||
fprintf(stderr, "Processing the file with the following changes:\n");
|
||||
fprintf(stderr, " tempo change = %+lg %%\n", params.tempoDelta);
|
||||
fprintf(stderr, " pitch change = %+lg semitones\n", params.pitchDelta);
|
||||
fprintf(stderr, " rate change = %+lg %%\n\n", params.rateDelta);
|
||||
fprintf(stderr, " tempo change = %+g %%\n", params.tempoDelta);
|
||||
fprintf(stderr, " pitch change = %+g semitones\n", params.pitchDelta);
|
||||
fprintf(stderr, " rate change = %+g %%\n\n", params.rateDelta);
|
||||
fprintf(stderr, "Working...");
|
||||
}
|
||||
else
|
||||
@ -240,7 +240,7 @@ static void detectBPM(WavInFile& inFile, RunParameters& params)
|
||||
|
||||
if (bpmValue > 0)
|
||||
{
|
||||
fprintf(stderr, "Detected BPM rate %.1lf\n\n", bpmValue);
|
||||
fprintf(stderr, "Detected BPM rate %.1f\n\n", bpmValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -252,7 +252,7 @@ static void detectBPM(WavInFile& inFile, RunParameters& params)
|
||||
{
|
||||
// adjust tempo to given bpm
|
||||
params.tempoDelta = (params.goalBPM / bpmValue - 1.0f) * 100.0f;
|
||||
fprintf(stderr, "The file will be converted to %.1lf BPM\n\n", params.goalBPM);
|
||||
fprintf(stderr, "The file will be converted to %.1f BPM\n\n", params.goalBPM);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -301,7 +301,7 @@ void BPMDetect::updateXCorr(int process_samples)
|
||||
pBuffer = buffer->ptrBegin();
|
||||
|
||||
// calculate decay factor for xcorr filtering
|
||||
float xcorr_decay = (float)pow(0.5, process_samples / (XCORR_DECAY_TIME_CONSTANT * TARGET_SRATE));
|
||||
float xcorr_decay = (float)pow(0.5, 1.0 / (XCORR_DECAY_TIME_CONSTANT * TARGET_SRATE / process_samples));
|
||||
|
||||
// prescale pbuffer
|
||||
float tmp[XCORR_UPDATE_SEQUENCE];
|
||||
|
||||
@ -56,6 +56,7 @@ using namespace soundtouch;
|
||||
FIRFilter::FIRFilter()
|
||||
{
|
||||
resultDivFactor = 0;
|
||||
resultDivider = 0;
|
||||
length = 0;
|
||||
lengthDiv8 = 0;
|
||||
filterCoeffs = nullptr;
|
||||
@ -154,7 +155,7 @@ uint FIRFilter::evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uin
|
||||
assert(src != nullptr);
|
||||
assert(dest != nullptr);
|
||||
assert(filterCoeffs != nullptr);
|
||||
assert(numChannels <= SOUNDTOUCH_MAX_CHANNELS);
|
||||
assert(numChannels < 16);
|
||||
|
||||
// hint compiler autovectorization that loop length is divisible by 8
|
||||
int ilength = length & -8;
|
||||
@ -206,24 +207,24 @@ void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint u
|
||||
assert(newLength > 0);
|
||||
if (newLength % 8) ST_THROW_RT_ERROR("FIR filter length not divisible by 8");
|
||||
|
||||
#ifdef SOUNDTOUCH_FLOAT_SAMPLES
|
||||
// scale coefficients already here if using floating samples
|
||||
double scale = 1.0 / resultDivider;
|
||||
#else
|
||||
short scale = 1;
|
||||
#endif
|
||||
|
||||
lengthDiv8 = newLength / 8;
|
||||
length = lengthDiv8 * 8;
|
||||
assert(length == newLength);
|
||||
|
||||
resultDivFactor = uResultDivFactor;
|
||||
resultDivider = (SAMPLETYPE)::pow(2.0, (int)resultDivFactor);
|
||||
|
||||
delete[] filterCoeffs;
|
||||
filterCoeffs = new SAMPLETYPE[length];
|
||||
delete[] filterCoeffsStereo;
|
||||
filterCoeffsStereo = new SAMPLETYPE[length*2];
|
||||
|
||||
#ifdef SOUNDTOUCH_FLOAT_SAMPLES
|
||||
// scale coefficients already here if using floating samples
|
||||
const double scale = ::pow(0.5, (int)resultDivFactor);;
|
||||
#else
|
||||
const short scale = 1;
|
||||
#endif
|
||||
|
||||
for (uint i = 0; i < length; i ++)
|
||||
{
|
||||
filterCoeffs[i] = (SAMPLETYPE)(coeffs[i] * scale);
|
||||
|
||||
@ -52,6 +52,9 @@ protected:
|
||||
// Result divider factor in 2^k format
|
||||
uint resultDivFactor;
|
||||
|
||||
// Result divider value.
|
||||
SAMPLETYPE resultDivider;
|
||||
|
||||
// Memory for filter coefficients
|
||||
SAMPLETYPE *filterCoeffs;
|
||||
SAMPLETYPE *filterCoeffsStereo;
|
||||
|
||||
@ -211,6 +211,9 @@ FIRFilterSSE::~FIRFilterSSE()
|
||||
// (overloaded) Calculates filter coefficients for SSE routine
|
||||
void FIRFilterSSE::setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor)
|
||||
{
|
||||
uint i;
|
||||
float fDivider;
|
||||
|
||||
FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);
|
||||
|
||||
// Scale the filter coefficients so that it won't be necessary to scale the filtering result
|
||||
@ -220,13 +223,13 @@ void FIRFilterSSE::setCoefficients(const float *coeffs, uint newLength, uint uRe
|
||||
filterCoeffsUnalign = new float[2 * newLength + 4];
|
||||
filterCoeffsAlign = (float *)SOUNDTOUCH_ALIGN_POINTER_16(filterCoeffsUnalign);
|
||||
|
||||
const float scale = ::pow(0.5, (int)resultDivFactor);
|
||||
fDivider = (float)resultDivider;
|
||||
|
||||
// rearrange the filter coefficients for sse routines
|
||||
for (auto i = 0U; i < newLength; i ++)
|
||||
// rearrange the filter coefficients for mmx routines
|
||||
for (i = 0; i < newLength; i ++)
|
||||
{
|
||||
filterCoeffsAlign[2 * i + 0] =
|
||||
filterCoeffsAlign[2 * i + 1] = coeffs[i] * scale;
|
||||
filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user