mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-25 09:57:32 +09:00
Issue #451 part 1 - use OpenMP for SoundTouch
This commit is contained in:
parent
952767296d
commit
b66a74daf6
5 changed files with 48 additions and 18 deletions
|
|
@ -86,8 +86,11 @@ uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, ui
|
|||
assert((length != 0) && (length == ilength) && (src != NULL) && (dest != NULL) && (filterCoeffs != NULL));
|
||||
|
||||
end = 2 * (numSamples - ilength);
|
||||
const SAMPLETYPE *coeffsStereo = filterCoeffsStereo;
|
||||
|
||||
#pragma omp parallel for
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel for default(none) shared(src, dest, end, ilength, coeffsStereo) private(j) schedule(static)
|
||||
#endif
|
||||
for (j = 0; j < end; j += 2)
|
||||
{
|
||||
const SAMPLETYPE *ptr;
|
||||
|
|
@ -98,8 +101,8 @@ uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, ui
|
|||
|
||||
for (int i = 0; i < ilength; i ++)
|
||||
{
|
||||
suml += ptr[2 * i] * filterCoeffsStereo[2 * i];
|
||||
sumr += ptr[2 * i + 1] * filterCoeffsStereo[2 * i + 1];
|
||||
suml += ptr[2 * i] * coeffsStereo[2 * i];
|
||||
sumr += ptr[2 * i + 1] * coeffsStereo[2 * i + 1];
|
||||
}
|
||||
|
||||
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||
|
|
@ -133,7 +136,10 @@ uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint
|
|||
assert(ilength != 0);
|
||||
|
||||
end = numSamples - ilength;
|
||||
#pragma omp parallel for
|
||||
const SAMPLETYPE *coeffs = filterCoeffs;
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel for default(none) shared(src, dest, end, ilength, coeffs) private(j) schedule(static)
|
||||
#endif
|
||||
for (j = 0; j < end; j ++)
|
||||
{
|
||||
const SAMPLETYPE *pSrc = src + j;
|
||||
|
|
@ -143,7 +149,7 @@ uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint
|
|||
sum = 0;
|
||||
for (i = 0; i < ilength; i ++)
|
||||
{
|
||||
sum += pSrc[i] * filterCoeffs[i];
|
||||
sum += pSrc[i] * coeffs[i];
|
||||
}
|
||||
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||
sum >>= resultDivFactor;
|
||||
|
|
@ -176,8 +182,11 @@ uint FIRFilter::evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uin
|
|||
int ilength = length & -8;
|
||||
|
||||
end = numChannels * (numSamples - ilength);
|
||||
const SAMPLETYPE *coeffs = filterCoeffs;
|
||||
|
||||
#pragma omp parallel for
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel for default(none) shared(src, dest, end, ilength, numChannels, coeffs) private(j) schedule(static)
|
||||
#endif
|
||||
for (j = 0; j < end; j += numChannels)
|
||||
{
|
||||
const SAMPLETYPE *ptr;
|
||||
|
|
@ -194,7 +203,7 @@ uint FIRFilter::evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uin
|
|||
|
||||
for (i = 0; i < ilength; i ++)
|
||||
{
|
||||
SAMPLETYPE coef=filterCoeffs[i];
|
||||
SAMPLETYPE coef=coeffs[i];
|
||||
for (c = 0; c < numChannels; c ++)
|
||||
{
|
||||
sums[c] += ptr[0] * coef;
|
||||
|
|
|
|||
|
|
@ -306,25 +306,31 @@ int TDStretch::seekBestOverlapPositionFull(const SAMPLETYPE *refPos)
|
|||
// over the permitted range.
|
||||
bestCorr = calcCrossCorr(refPos, pMidBuffer, norm);
|
||||
bestCorr = (bestCorr + 0.1) * 0.75;
|
||||
const int seekLen = seekLength;
|
||||
const int nChannels = channels;
|
||||
const SAMPLETYPE *midBuffer = pMidBuffer;
|
||||
|
||||
#pragma omp parallel for
|
||||
for (i = 1; i < seekLength; i ++)
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel for default(none) shared(refPos, bestCorr, bestOffs, seekLen, nChannels, midBuffer) private(i) schedule(static)
|
||||
#endif
|
||||
for (i = 1; i < seekLen; i ++)
|
||||
{
|
||||
double corr;
|
||||
double localNorm;
|
||||
// Calculates correlation value for the mixing position corresponding to 'i'
|
||||
#if defined(_OPENMP) || defined(ST_SIMD_AVOID_UNALIGNED)
|
||||
// in parallel OpenMP mode, can't use norm accumulator version as parallel executor won't
|
||||
// iterate the loop in sequential order
|
||||
// in SIMD mode, avoid accumulator version to allow avoiding unaligned positions
|
||||
corr = calcCrossCorr(refPos + channels * i, pMidBuffer, norm);
|
||||
corr = calcCrossCorr(refPos + nChannels * i, midBuffer, localNorm);
|
||||
#else
|
||||
// In non-parallel version call "calcCrossCorrAccumulate" that is otherwise same
|
||||
// as "calcCrossCorr", but saves time by reusing & updating previously stored
|
||||
// "norm" value
|
||||
corr = calcCrossCorrAccumulate(refPos + channels * i, pMidBuffer, norm);
|
||||
corr = calcCrossCorrAccumulate(refPos + nChannels * i, midBuffer, norm);
|
||||
#endif
|
||||
// heuristic rule to slightly favour values close to mid of the range
|
||||
double tmp = (double)(2 * i - seekLength) / (double)seekLength;
|
||||
double tmp = (double)(2 * i - seekLen) / (double)seekLen;
|
||||
corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
|
||||
|
||||
// Checks for the highest correlation value
|
||||
|
|
@ -333,7 +339,9 @@ int TDStretch::seekBestOverlapPositionFull(const SAMPLETYPE *refPos)
|
|||
// For optimal performance, enter critical section only in case that best value found.
|
||||
// in such case repeat 'if' condition as it's possible that parallel execution may have
|
||||
// updated the bestCorr value in the mean time
|
||||
#pragma omp critical
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp critical(soundtouch_bestcorr)
|
||||
#endif
|
||||
if (corr > bestCorr)
|
||||
{
|
||||
bestCorr = corr;
|
||||
|
|
@ -910,7 +918,9 @@ double TDStretch::calcCrossCorr(const short *mixingPos, const short *compare, do
|
|||
if (lnorm > maxnorm)
|
||||
{
|
||||
// modify 'maxnorm' inside critical section to avoid multi-access conflict if in OpenMP mode
|
||||
#pragma omp critical
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp critical(soundtouch_maxnorm)
|
||||
#endif
|
||||
if (lnorm > maxnorm)
|
||||
{
|
||||
maxnorm = lnorm;
|
||||
|
|
|
|||
|
|
@ -119,7 +119,9 @@ double TDStretchMMX::calcCrossCorr(const short *pV1, const short *pV2, double &d
|
|||
if (norm > (long)maxnorm)
|
||||
{
|
||||
// modify 'maxnorm' inside critical section to avoid multi-access conflict if in OpenMP mode
|
||||
#pragma omp critical
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp critical(soundtouch_maxnorm)
|
||||
#endif
|
||||
if (norm > (long)maxnorm)
|
||||
{
|
||||
maxnorm = norm;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,11 @@ else:
|
|||
# Windows need alloca renamed to _alloca
|
||||
DEFINES['alloca'] = '_alloca'
|
||||
|
||||
# Use standardized OpenMP parallelization for SoundTouch hot loops.
|
||||
if CONFIG['CC_TYPE'] == 'gcc':
|
||||
CXXFLAGS += ['-fopenmp']
|
||||
OS_LIBS += ['gomp']
|
||||
|
||||
DEFINES['BUILDING_SOUNDTOUCH'] = 1
|
||||
|
||||
# We allow warnings for third-party code that can be updated from upstream.
|
||||
|
|
|
|||
|
|
@ -250,9 +250,13 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n
|
|||
assert((length % 8) == 0);
|
||||
assert(filterCoeffsAlign != NULL);
|
||||
assert(((ulongptr)filterCoeffsAlign) % 16 == 0);
|
||||
const uint filterLength = length;
|
||||
const float *coeffsAlign = filterCoeffsAlign;
|
||||
|
||||
// filter is evaluated for two stereo samples with each iteration, thus use of 'j += 2'
|
||||
#pragma omp parallel for
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel for default(none) shared(source, dest, count, filterLength, coeffsAlign) private(j) schedule(static)
|
||||
#endif
|
||||
for (j = 0; j < count; j += 2)
|
||||
{
|
||||
const float *pSrc;
|
||||
|
|
@ -263,11 +267,11 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n
|
|||
|
||||
pSrc = (const float*)source + j * 2; // source audio data
|
||||
pDest = dest + j * 2; // destination audio data
|
||||
pFil = (const __m128*)filterCoeffsAlign; // filter coefficients. NOTE: Assumes coefficients
|
||||
pFil = (const __m128*)coeffsAlign; // filter coefficients. NOTE: Assumes coefficients
|
||||
// are aligned to 16-byte boundary
|
||||
sum1 = sum2 = _mm_setzero_ps();
|
||||
|
||||
for (i = 0; i < length / 8; i ++)
|
||||
for (i = 0; i < filterLength / 8; i ++)
|
||||
{
|
||||
// Unroll loop for efficiency & calculate filter for 2*2 stereo samples
|
||||
// at each pass
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue