Skip to content

Commit

Permalink
per-Bungee-instance FFT cache
Browse files Browse the repository at this point in the history
  • Loading branch information
kupix committed Oct 19, 2024
1 parent bca568c commit f7a54a5
Show file tree
Hide file tree
Showing 10 changed files with 33 additions and 46 deletions.
9 changes: 5 additions & 4 deletions src/Basic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ bool Stretcher<Basic>::isFlushed() const

Basic::Basic(SampleRates sampleRates, int channelCount, int log2SynthesisHopOverride) :
Timing(sampleRates, log2SynthesisHopOverride),
input(log2SynthesisHop, channelCount),
transforms(Fourier::transforms()),
input(log2SynthesisHop, channelCount, *transforms),
grains(4),
output(log2SynthesisHop, channelCount, maxOutputFrameCount(true), 0.25f, {1.f, 0.5f})
output(*transforms, log2SynthesisHop, channelCount, maxOutputFrameCount(true), 0.25f, {1.f, 0.5f})
{
for (auto &grain : grains.vector)
grain = std::make_unique<Grain>(log2SynthesisHop, channelCount);
Expand Down Expand Up @@ -68,7 +69,7 @@ void Basic::analyseGrain(const float *data, std::ptrdiff_t stride)

auto log2TransformLength = input.applyAnalysisWindow(ref);

Fourier::transforms->forward(log2TransformLength, input.windowedInput, grain.transformed);
transforms->forward(log2TransformLength, input.windowedInput, grain.transformed);

const auto n = Fourier::binCount(grain.log2TransformLength) - 1;
grain.validBinCount = std::min<int>(std::ceil(n / grain.resampleOperations.output.ratio), n) + 1;
Expand Down Expand Up @@ -112,7 +113,7 @@ void Basic::synthesiseGrain(OutputChunk &outputChunk)
else
grain.transformed.topRows(grain.validBinCount).colwise() *= t;

Fourier::transforms->inverse(grain.log2TransformLength, output.inverseTransformed, grain.transformed);
transforms->inverse(grain.log2TransformLength, output.inverseTransformed, grain.transformed);
}

output.applySynthesisWindow(log2SynthesisHop, grains, output.synthesisWindow);
Expand Down
4 changes: 3 additions & 1 deletion src/Basic.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
#include "Output.h"
#include "Timing.h"

#include <memory>

namespace Bungee {

struct Basic :
Fourier::Bootstrap,
Timing
{
std::unique_ptr<Fourier::Transforms> transforms;
Input input;
Grains grains;
Output output;
Expand Down
8 changes: 2 additions & 6 deletions src/Fourier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,9 @@ void Kiss::Kernel<isInverse>::inverse(int, float *t, std::complex<float> *f) con
kiss_fftri((kiss_fftr_cfg)implementation, (kiss_fft_cpx *)f, t);
}

Transforms *transforms{};

Bootstrap::Bootstrap()
std::unique_ptr<Transforms> transforms()
{
BUNGEE_ASSERT1(!transforms);
static Fourier::Cache<Kiss, 16> cache;
BUNGEE_ASSERT1(transforms == &cache);
return std::make_unique<Cache<Kiss, 16>>();
}

} // namespace Bungee::Fourier
32 changes: 9 additions & 23 deletions src/Fourier.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include <complex>
#include <limits>
#include <memory>
#include <mutex>
#include <vector>

namespace Bungee {
Expand Down Expand Up @@ -68,14 +67,12 @@ inline void resize(int log2TransformLength, int channelCount, T &array, int extr
struct Transforms
{
virtual ~Transforms() {}
virtual void prepareForward(int log2Length) = 0;
virtual void prepareInverse(int log2Length) = 0;
virtual void prepareForward(int log2TransformLength) = 0;
virtual void prepareInverse(int log2TransformLength) = 0;
virtual void forward(int log2TransformLength, const Eigen::Ref<const Eigen::ArrayXXf> &t, Eigen::Ref<Eigen::ArrayXXcf> f) const = 0;
virtual void inverse(int log2TransformLength, Eigen::Ref<Eigen::ArrayXXf> t, const Eigen::Ref<const Eigen::ArrayXXcf> &f) const = 0;
};

extern Transforms *transforms;

// General case when an FFT implementation has different states for forward and reverse transforms of same size.
template <class F, class I>
struct KernelPair
Expand Down Expand Up @@ -129,27 +126,19 @@ struct Cache :
{
typedef KernelPair<typename K::Forward, typename K::Inverse> Entry;
typedef std::array<Entry, log2MaxSize + 1> Table;
std::mutex preparationMutex;

Table table;

Cache()
{
transforms = this;
}

void prepareForward(int log2Length) override
void prepareForward(int log2TransformLength) override
{
std::scoped_lock lock(preparationMutex);
if (!table[log2Length].forward())
table[log2Length].forward(new typename K::Forward(log2Length));
if (!table[log2TransformLength].forward())
table[log2TransformLength].forward(new typename K::Forward(log2TransformLength));
}

void prepareInverse(int log2Length) override
void prepareInverse(int log2TransformLength) override
{
std::scoped_lock lock(preparationMutex);
if (!table[log2Length].inverse())
table[log2Length].inverse(new typename K::Inverse(log2Length));
if (!table[log2TransformLength].inverse())
table[log2TransformLength].inverse(new typename K::Inverse(log2TransformLength));
}

void forward(int log2TransformLength, const Eigen::Ref<const Eigen::ArrayXXf> &t, Eigen::Ref<Eigen::ArrayXXcf> f) const override
Expand Down Expand Up @@ -177,9 +166,6 @@ struct Cache :
}
};

struct Bootstrap
{
Bootstrap();
};
std::unique_ptr<Transforms> transforms();

} // namespace Bungee::Fourier
6 changes: 3 additions & 3 deletions src/Input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ static constexpr float pi = std::numbers::pi_v<float>;
static constexpr float gain = (3 * pi) / (3 * pi + 8);
} // namespace

Input::Input(int log2SynthesisHop, int channelCount) :
analysisWindowBasic(Window::fromFrequencyDomainCoefficients(log2SynthesisHop + 3, gain / (8 << log2SynthesisHop), {1.f, 0.5f})),
Input::Input(int log2SynthesisHop, int channelCount, Fourier::Transforms &transforms) :
analysisWindowBasic(Window::fromFrequencyDomainCoefficients(transforms, log2SynthesisHop + 3, gain / (8 << log2SynthesisHop), {1.f, 0.5f})),
windowedInput{(8 << log2SynthesisHop), channelCount}
{
windowedInput.setZero();
Fourier::transforms->prepareForward(log2SynthesisHop + 3);
transforms.prepareForward(log2SynthesisHop + 3);
}

int Input::applyAnalysisWindow(const Eigen::Ref<const Eigen::ArrayXXf> &input)
Expand Down
3 changes: 2 additions & 1 deletion src/Input.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#pragma once

#include "Assert.h"
#include "Fourier.h"

#include <Eigen/Dense>

Expand All @@ -14,7 +15,7 @@ struct Input
Eigen::ArrayXf analysisWindowBasic;
Eigen::ArrayXXf windowedInput;

Input(int log2SynthesisHop, int channelCount);
Input(int log2SynthesisHop, int channelCount, Fourier::Transforms &transforms);

int applyAnalysisWindow(const Eigen::Ref<const Eigen::ArrayXXf> &input);
};
Expand Down
6 changes: 3 additions & 3 deletions src/Output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@

namespace Bungee {

Output::Output(int log2SynthesisHop, int channelCount, int maxOutputChunkSize, float windowGain, std::initializer_list<float> windowCoefficients) :
synthesisWindow{Window::fromFrequencyDomainCoefficients(log2SynthesisHop + 2, windowGain, windowCoefficients)},
Output::Output(Fourier::Transforms &transforms, int log2SynthesisHop, int channelCount, int maxOutputChunkSize, float windowGain, std::initializer_list<float> windowCoefficients) :
synthesisWindow{Window::fromFrequencyDomainCoefficients(transforms, log2SynthesisHop + 2, windowGain, windowCoefficients)},
inverseTransformed(8 << log2SynthesisHop, channelCount),
bufferResampled(maxOutputChunkSize, channelCount)
{
Fourier::transforms->prepareInverse(log2SynthesisHop + 3);
transforms.prepareInverse(log2SynthesisHop + 3);
}

void Output::applySynthesisWindow(int log2SynthesisHop, Grains &grains, const Eigen::Ref<const Eigen::ArrayXf> &window)
Expand Down
2 changes: 1 addition & 1 deletion src/Output.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct Output
float resampleOffset = 0.f;
Window::DispatchApply dispatchApply;

Output(int log2SynthesisHop, int channelCount, int maxOutputChunkSize, float windowGain, std::initializer_list<float> windowCoefficients);
Output(Fourier::Transforms &transforms, int log2SynthesisHop, int channelCount, int maxOutputChunkSize, float windowGain, std::initializer_list<float> windowCoefficients);

void applySynthesisWindow(int log2SynthesisHop, Grains &grains, const Eigen::Ref<const Eigen::ArrayXf> &window);

Expand Down
6 changes: 3 additions & 3 deletions src/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace Bungee::Window {

Eigen::ArrayXf fromFrequencyDomainCoefficients(int log2Size, float gain, std::initializer_list<float> coefficients)
Eigen::ArrayXf fromFrequencyDomainCoefficients(Fourier::Transforms &transforms, int log2Size, float gain, std::initializer_list<float> coefficients)
{
Eigen::ArrayXcf frequencyDomain(Fourier::binCount(log2Size));

Expand All @@ -22,8 +22,8 @@ Eigen::ArrayXf fromFrequencyDomainCoefficients(int log2Size, float gain, std::in
frequencyDomain.bottomRows(frequencyDomain.rows() - i).setZero();

Eigen::ArrayXf window(1 << log2Size);
Fourier::transforms->prepareInverse(log2Size);
Fourier::transforms->inverse(log2Size, window, frequencyDomain);
transforms.prepareInverse(log2Size);
transforms.inverse(log2Size, window, frequencyDomain);
return window;
}

Expand Down
3 changes: 2 additions & 1 deletion src/Window.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@

#include "Assert.h"
#include "Dispatch.h"
#include "Fourier.h"

#include <Eigen/Dense>

#include <initializer_list>

namespace Bungee::Window {

Eigen::ArrayXf fromFrequencyDomainCoefficients(int log2Size, float gain, std::initializer_list<float> coefficients);
Eigen::ArrayXf fromFrequencyDomainCoefficients(Fourier::Transforms &transforms, int log2Size, float gain, std::initializer_list<float> coefficients);

struct Apply
{
Expand Down

0 comments on commit f7a54a5

Please sign in to comment.