separated AAX from normal build so that pffft could be used instead for licensing purposes. prevent file position jump when changing prebuffering. eliminate unecessary fft size calculations

This commit is contained in:
essej
2022-04-26 17:58:45 -04:00
parent cc80d951ea
commit 774031a7a9
13 changed files with 2253 additions and 36 deletions

View File

@ -58,6 +58,13 @@ FFT::FFT(int nsamples_, bool no_inverse)
m_workReal.resize(nsamples,false);
m_workImag.resize(nsamples,false);
//Logger::writeToLog("fftsize: " + String(nsamples) + " log2N: " + String(log2N));
#elif PS_USE_PFFFT
planpffft = pffft_new_setup(nsamples, PFFFT_REAL);
m_work.resize(2*nsamples,false);
//Logger::writeToLog("fftsize: " + String(nsamples) + " log2N: " + String(log2N));
#else
@ -88,6 +95,10 @@ FFT::~FFT()
{
#if PS_USE_VDSP_FFT
vDSP_destroy_fftsetup((FFTSetup)planfft);
#elif PS_USE_PFFFT
if (planpffft) {
pffft_destroy_setup(planpffft);
}
#else
fftwf_destroy_plan(planfftw);
if (planifftw!=nullptr)
@ -139,6 +150,24 @@ void FFT::smp2freq()
freq[0] = 0.0;
#elif PS_USE_PFFFT
const int halfsamples = nsamples / 2;
auto * databuf = data.data();
pffft_transform_ordered(planpffft, smp.data(), databuf, m_work.data(), PFFFT_FORWARD);
data[1] = 0.0f;
// compute magnitude
FloatVectorOperations::multiply(databuf, databuf, nsamples);
for (int k=1, l=2; k < halfsamples; ++k, l+=2) {
freq[k] = sqrt(databuf[l] + databuf[l+1]);
}
freq[0] = 0.0;
#else
for (int i=0;i<nsamples;i++)
@ -192,7 +221,29 @@ void FFT::freq2smp()
vDSP_vsmul(data.data(), 1, &scale, smp.data(), 1, nsamples);
#elif PS_USE_PFFFT
const int halfsamples = nsamples / 2;
auto * databuf = data.data();
for (int i=1; i < halfsamples; ++i)
{
unsigned int rand = m_randdist(m_randgen);
REALTYPE phase=rand*inv_2p15_2pi;
data[i*2] = freq[i]*cos(phase);
data[i*2+1] = freq[i]*sin(phase);
};
data[0] = data[1] = 0.0;
pffft_transform_ordered(planpffft, databuf, smp.data(), m_work.data(), PFFFT_BACKWARD);
// post scale
float scale = 1.f / nsamples;
FloatVectorOperations::multiply(smp.data(), scale, nsamples);
#else
for (int i=1;i<nsamples/2;i++)
{
unsigned int rand = m_randdist(m_randgen);
@ -204,8 +255,11 @@ void FFT::freq2smp()
data[0]=data[nsamples/2+1]=data[nsamples/2]=0.0;
fftwf_execute(planifftw);
for (int i=0;i<nsamples;i++)
smp[i]=data[i]/nsamples;
// post scale
float scale = 1.f / nsamples;
FloatVectorOperations::multiply(smp.data(), data.data(), scale, nsamples);
#endif
};

View File

@ -26,11 +26,19 @@
#define PS_USE_VDSP_FFT 0
#endif
#ifndef PS_USE_PFFFT
#define PS_USE_PFFFT 0
#endif
#if PS_USE_VDSP_FFT
#elif PS_USE_PFFFT
#include "../pffft/pffft.h"
#else
#include "fftw3.h"
#endif
#include "../JuceLibraryCode/JuceHeader.h"
#include <random>
#include <type_traits>
@ -107,6 +115,11 @@ private:
buf = (float*)malloc(size*sizeof(float));
else
buf = (double*)malloc(size * sizeof(double));
#elif PS_USE_PFFFT
if constexpr (std::is_same<T,float>::value)
buf = (float*)pffft_aligned_malloc(size*sizeof(float));
else
buf = (double*)pffft_aligned_malloc(size * sizeof(double));
#else
if constexpr (std::is_same<T,float>::value)
buf = (float*)fftwf_malloc(size*sizeof(float));
@ -123,6 +136,11 @@ private:
free(buf);
else
free(buf);
#elif PS_USE_PFFFT
if constexpr (std::is_same<T, float>::value)
pffft_aligned_free(buf);
else
pffft_aligned_free(buf);
#else
if constexpr (std::is_same<T, float>::value)
fftwf_free(buf);
@ -159,6 +177,9 @@ class FFT
int log2N;
FFTWBuffer<REALTYPE> m_workReal;
FFTWBuffer<REALTYPE> m_workImag;
#elif PS_USE_PFFFT
PFFFT_Setup *planpffft = nullptr;
FFTWBuffer<REALTYPE> m_work;
#else
fftwf_plan planfftw,planifftw;
#endif

View File

@ -599,6 +599,14 @@ void StretchAudioSource::playDrySound(const AudioSourceChannelInfo & bufferToFil
bufs[i][j + bufferToFill.startSample] = maingain * m_resampler_outbuf[j*m_num_outchans + i];
}
double StretchAudioSource::getLastSourcePositionPercent()
{
if (m_inputfile == nullptr || m_inputfile->info.nsamples == 0)
return 0.0;
return (1.0/m_inputfile->info.nsamples)*m_last_filepos;
}
double StretchAudioSource::getInfilePositionPercent()
{
if (m_inputfile == nullptr || m_inputfile->info.nsamples == 0)
@ -686,6 +694,8 @@ void StretchAudioSource::setFFTSize(int size, bool force)
jassert(size>0);
if (force || (m_xfadetask.state == 0 && (m_process_fftsize == 0 || size != m_process_fftsize)))
{
DBG("Using FFT size: " << size);
ScopedLock locker(m_cs);
if (m_xfadetask.buffer.getNumChannels() < m_num_outchans)
{
@ -704,7 +714,8 @@ void StretchAudioSource::setFFTSize(int size, bool force)
m_process_fftsize = size;
initObjects();
}
++m_param_change_count;
}
}

View File

@ -100,6 +100,8 @@ public:
double getLastSeekPos() const { return m_seekpos; }
CriticalSection* getMutex() { return &m_cs; }
int64_t getLastSourcePosition() const { return m_last_filepos; }
double getLastSourcePositionPercent();
int m_prebuffersize = 0;
void setSpectralOrderPreset(int id);

View File

@ -288,7 +288,7 @@ inline String secondsToString2(double secs)
result.preallocateBytes(32);
bool empty = true;
if ((int)rt.inHours()>0)
result << String((int)rt.inHours() % 24).paddedLeft('0', empty ? 1 : 2) << ':';
result << String((int)rt.inHours()).paddedLeft('0', empty ? 1 : 2) << ':';
result << String((int)rt.inMinutes() % 60).paddedLeft('0', 2) << ':';
result << String((int)rt.inSeconds() % 60).paddedLeft('0', 2);
auto millis = (int)rt.inMilliseconds() % 1000;