Compare commits

..

No commits in common. "master" and "2.3.3" have entirely different histories.

11 changed files with 44 additions and 43 deletions

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.1)
project(SoundTouch VERSION 2.3.3 LANGUAGES CXX) project(SoundTouch VERSION 2.3.3 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
@ -13,8 +13,7 @@ else()
if(EMSCRIPTEN) if(EMSCRIPTEN)
list(APPEND COMPILE_OPTIONS -O3) list(APPEND COMPILE_OPTIONS -O3)
else() else()
# Apply -ffast-math to allow compiler autovectorization generate effective SIMD code for arm compilation list(APPEND COMPILE_OPTIONS -Ofast)
list(APPEND COMPILE_OPTIONS -O3 -ffast-math)
endif() endif()
endif() endif()
@ -97,7 +96,6 @@ install(
include/soundtouch_config.h include/soundtouch_config.h
DESTINATION DESTINATION
"${CMAKE_INSTALL_INCLUDEDIR}/soundtouch" "${CMAKE_INSTALL_INCLUDEDIR}/soundtouch"
COMPONENT SoundTouch
) )
install(TARGETS SoundTouch install(TARGETS SoundTouch
@ -106,7 +104,6 @@ install(TARGETS SoundTouch
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
COMPONENT SoundTouch
) )
####################### #######################
@ -129,7 +126,6 @@ if(SOUNDSTRETCH)
install(TARGETS soundstretch install(TARGETS soundstretch
DESTINATION bin DESTINATION bin
COMPONENT soundstretch
) )
endif() endif()
@ -148,8 +144,8 @@ if(SOUNDTOUCH_DLL)
target_compile_definitions(SoundTouchDLL PRIVATE DLL_EXPORTS) target_compile_definitions(SoundTouchDLL PRIVATE DLL_EXPORTS)
target_include_directories(SoundTouchDLL PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>) target_include_directories(SoundTouchDLL PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
target_link_libraries(SoundTouchDLL PRIVATE SoundTouch) target_link_libraries(SoundTouchDLL PRIVATE SoundTouch)
install(FILES source/SoundTouchDLL/SoundTouchDLL.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/soundtouch" COMPONENT SoundTouchDLL) install(FILES source/SoundTouchDLL/SoundTouchDLL.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/soundtouch")
install(TARGETS SoundTouchDLL EXPORT SoundTouchTargets COMPONENT SoundTouchDLL) install(TARGETS SoundTouchDLL EXPORT SoundTouchTargets)
endif() endif()
######################## ########################
@ -161,7 +157,7 @@ set(libdir "\${prefix}/${CMAKE_INSTALL_LIBDIR}")
set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
set(VERSION "${CMAKE_PROJECT_VERSION}") set(VERSION "${CMAKE_PROJECT_VERSION}")
configure_file(soundtouch.pc.in "${CMAKE_CURRENT_BINARY_DIR}/soundtouch.pc" @ONLY) 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 # CMake config
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
@ -171,7 +167,6 @@ install(
FILE SoundTouchTargets.cmake FILE SoundTouchTargets.cmake
NAMESPACE SoundTouch:: NAMESPACE SoundTouch::
DESTINATION "${SOUNDTOUCH_INSTALL_CMAKEDIR}" DESTINATION "${SOUNDTOUCH_INSTALL_CMAKEDIR}"
COMPONENT SoundTouch
) )
configure_package_config_file(SoundTouchConfig.cmake.in configure_package_config_file(SoundTouchConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/SoundTouchConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/SoundTouchConfig.cmake"
@ -187,5 +182,4 @@ install(
"${CMAKE_CURRENT_BINARY_DIR}/SoundTouchConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/SoundTouchConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/SoundTouchConfigVersion.cmake" "${CMAKE_CURRENT_BINARY_DIR}/SoundTouchConfigVersion.cmake"
DESTINATION "${SOUNDTOUCH_INSTALL_CMAKEDIR}" DESTINATION "${SOUNDTOUCH_INSTALL_CMAKEDIR}"
COMPONENT SoundTouch
) )

View File

@ -205,7 +205,7 @@
separate mono channels, this isn't recommended because processing the separate mono channels, this isn't recommended because processing the
channels separately would result in losing the phase coherency between channels separately would result in losing the phase coherency between
the channels, which consequently would ruin the stereo effect.</p> 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> <h3>3.2. Processing latency</h3>
<p>The processing and latency constraints of the SoundTouch library are:</p> <p>The processing and latency constraints of the SoundTouch library are:</p>
<ul> <ul>

View File

@ -31,8 +31,9 @@ AC_DISABLE_STATIC dnl This makes libtool only build shared libs
AC_LANG(C++) AC_LANG(C++)
# Compiler flags. Apply -ffast-math to allow compiler autovectorization generate effective SIMD code for arm compilation # Compiler flags. Apply -Ofast (implies -O3 -ffast-math) to allow gcc autovectorization
CXXFLAGS="${CXXFLAGS} -O3 -ffast-math -Wall -Wextra -Wzero-as-null-pointer-constant -Wno-unknown-pragmas" # 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')" # Set AR_FLAGS to avoid build warning "ar: `u' modifier ignored since `D' is the default (see `U')"
AR_FLAGS='cr' AR_FLAGS='cr'

View File

@ -56,9 +56,8 @@ typedef unsigned long ulong;
namespace soundtouch namespace soundtouch
{ {
/// Max allowed number of channels. This is not a hard limit but to have some /// Max allowed number of channels
/// maximum value for argument sanity checks -- can be increased if necessary #define SOUNDTOUCH_MAX_CHANNELS 16
#define SOUNDTOUCH_MAX_CHANNELS 32
/// Activate these undef's to overrule the possible sampletype /// Activate these undef's to overrule the possible sampletype
/// setting inherited from some other header file: /// setting inherited from some other header file:

View File

@ -199,7 +199,7 @@ void RunParameters::throwLicense() const
ST_THROW_RT_ERROR(licenseText); ST_THROW_RT_ERROR(licenseText);
} }
double RunParameters::parseSwitchValue(const STRING& str) const float RunParameters::parseSwitchValue(const STRING& str) const
{ {
int pos; int pos;
@ -211,7 +211,7 @@ double RunParameters::parseSwitchValue(const STRING& str) const
} }
// Read numerical parameter value after '=' // Read numerical parameter value after '='
return stof(str.substr(pos + 1).c_str()); return (float)stof(str.substr(pos + 1).c_str());
} }

View File

@ -48,17 +48,17 @@ private:
void throwLicense() const; void throwLicense() const;
void parseSwitchParam(const STRING& str); void parseSwitchParam(const STRING& str);
void checkLimits(); void checkLimits();
double parseSwitchValue(const STRING& tr) const; float parseSwitchValue(const STRING& tr) const;
public: public:
STRING inFileName; STRING inFileName;
STRING outFileName; STRING outFileName;
double tempoDelta{ 0 }; float tempoDelta{ 0 };
double pitchDelta{ 0 }; float pitchDelta{ 0 };
double rateDelta{ 0 }; float rateDelta{ 0 };
int quick{ 0 }; int quick{ 0 };
int noAntiAlias{ 0 }; int noAntiAlias{ 0 };
double goalBPM{ 0 }; float goalBPM{ 0 };
bool detectBPM{ false }; bool detectBPM{ false };
bool speech{ false }; bool speech{ false };

View File

@ -145,9 +145,9 @@ static void setup(SoundTouch& soundTouch, const WavInFile& inFile, const RunPara
#endif #endif
// print processing information only if outFileName given i.e. some processing will happen // 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, "Processing the file with the following changes:\n");
fprintf(stderr, " tempo change = %+lg %%\n", params.tempoDelta); fprintf(stderr, " tempo change = %+g %%\n", params.tempoDelta);
fprintf(stderr, " pitch change = %+lg semitones\n", params.pitchDelta); fprintf(stderr, " pitch change = %+g semitones\n", params.pitchDelta);
fprintf(stderr, " rate change = %+lg %%\n\n", params.rateDelta); fprintf(stderr, " rate change = %+g %%\n\n", params.rateDelta);
fprintf(stderr, "Working..."); fprintf(stderr, "Working...");
} }
else else
@ -240,7 +240,7 @@ static void detectBPM(WavInFile& inFile, RunParameters& params)
if (bpmValue > 0) if (bpmValue > 0)
{ {
fprintf(stderr, "Detected BPM rate %.1lf\n\n", bpmValue); fprintf(stderr, "Detected BPM rate %.1f\n\n", bpmValue);
} }
else else
{ {
@ -252,7 +252,7 @@ static void detectBPM(WavInFile& inFile, RunParameters& params)
{ {
// adjust tempo to given bpm // adjust tempo to given bpm
params.tempoDelta = (params.goalBPM / bpmValue - 1.0f) * 100.0f; 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);
} }
} }

View File

@ -301,7 +301,7 @@ void BPMDetect::updateXCorr(int process_samples)
pBuffer = buffer->ptrBegin(); pBuffer = buffer->ptrBegin();
// calculate decay factor for xcorr filtering // 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 // prescale pbuffer
float tmp[XCORR_UPDATE_SEQUENCE]; float tmp[XCORR_UPDATE_SEQUENCE];

View File

@ -56,6 +56,7 @@ using namespace soundtouch;
FIRFilter::FIRFilter() FIRFilter::FIRFilter()
{ {
resultDivFactor = 0; resultDivFactor = 0;
resultDivider = 0;
length = 0; length = 0;
lengthDiv8 = 0; lengthDiv8 = 0;
filterCoeffs = nullptr; filterCoeffs = nullptr;
@ -154,7 +155,7 @@ uint FIRFilter::evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uin
assert(src != nullptr); assert(src != nullptr);
assert(dest != nullptr); assert(dest != nullptr);
assert(filterCoeffs != nullptr); assert(filterCoeffs != nullptr);
assert(numChannels <= SOUNDTOUCH_MAX_CHANNELS); assert(numChannels < 16);
// hint compiler autovectorization that loop length is divisible by 8 // hint compiler autovectorization that loop length is divisible by 8
int ilength = length & -8; int ilength = length & -8;
@ -206,24 +207,24 @@ void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint u
assert(newLength > 0); assert(newLength > 0);
if (newLength % 8) ST_THROW_RT_ERROR("FIR filter length not divisible by 8"); 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; lengthDiv8 = newLength / 8;
length = lengthDiv8 * 8; length = lengthDiv8 * 8;
assert(length == newLength); assert(length == newLength);
resultDivFactor = uResultDivFactor; resultDivFactor = uResultDivFactor;
resultDivider = (SAMPLETYPE)::pow(2.0, (int)resultDivFactor);
delete[] filterCoeffs; delete[] filterCoeffs;
filterCoeffs = new SAMPLETYPE[length]; filterCoeffs = new SAMPLETYPE[length];
delete[] filterCoeffsStereo; delete[] filterCoeffsStereo;
filterCoeffsStereo = new SAMPLETYPE[length*2]; 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 ++) for (uint i = 0; i < length; i ++)
{ {
filterCoeffs[i] = (SAMPLETYPE)(coeffs[i] * scale); filterCoeffs[i] = (SAMPLETYPE)(coeffs[i] * scale);

View File

@ -52,6 +52,9 @@ protected:
// Result divider factor in 2^k format // Result divider factor in 2^k format
uint resultDivFactor; uint resultDivFactor;
// Result divider value.
SAMPLETYPE resultDivider;
// Memory for filter coefficients // Memory for filter coefficients
SAMPLETYPE *filterCoeffs; SAMPLETYPE *filterCoeffs;
SAMPLETYPE *filterCoeffsStereo; SAMPLETYPE *filterCoeffsStereo;

View File

@ -211,6 +211,9 @@ FIRFilterSSE::~FIRFilterSSE()
// (overloaded) Calculates filter coefficients for SSE routine // (overloaded) Calculates filter coefficients for SSE routine
void FIRFilterSSE::setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor) void FIRFilterSSE::setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor)
{ {
uint i;
float fDivider;
FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor); FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);
// Scale the filter coefficients so that it won't be necessary to scale the filtering result // 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]; filterCoeffsUnalign = new float[2 * newLength + 4];
filterCoeffsAlign = (float *)SOUNDTOUCH_ALIGN_POINTER_16(filterCoeffsUnalign); 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 // rearrange the filter coefficients for mmx routines
for (auto i = 0U; i < newLength; i ++) for (i = 0; i < newLength; i ++)
{ {
filterCoeffsAlign[2 * i + 0] = filterCoeffsAlign[2 * i + 0] =
filterCoeffsAlign[2 * i + 1] = coeffs[i] * scale; filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider;
} }
} }