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:
@ -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
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user