Skip to content

WIP: Making Real-time objects allocator-aware #190

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 78 commits into from
Sep 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
315132c
Make HPSS allocator aware
weefuzzy Jul 19, 2022
dd93b4e
Add new memory header and updates to fluid tensor
weefuzzy Jul 19, 2022
fe1b05d
Add changes to FluidContext
weefuzzy Jul 19, 2022
7743742
Merge branch 'dev' into enhance/rtalloc
weefuzzy Jul 19, 2022
45aa9e1
add CMakeLists changes
weefuzzy Jul 19, 2022
53248d0
Commit FluidBaseClient changes
weefuzzy Jul 20, 2022
f5866d6
Improve alias names
weefuzzy Jul 20, 2022
0a0e075
use allocator in (STFT)BufferedProcess
weefuzzy Jul 20, 2022
a4bee9f
Update NRTWrapper to pass context
weefuzzy Jul 20, 2022
1676c7d
Add allocator to FluidTensor constructors (argh)
weefuzzy Jul 20, 2022
17e6297
Use default alloctor in MemoryBufferAdaptor
weefuzzy Jul 20, 2022
5c0e8a1
introduce type alias for FluidTensorView->Eigen Maps
weefuzzy Jul 20, 2022
857bc25
Update chroma to use allocators
weefuzzy Jul 20, 2022
8e28e26
Deal with integer conversion warnings, make buffered process construc…
weefuzzy Jul 21, 2022
305252a
Update OnsetSlice
weefuzzy Jul 21, 2022
ecb93bc
Make building examples conditional
weefuzzy Jul 21, 2022
94ef6ba
Mop up emerging boilerplate with RAII EigenMap + Vector thing
weefuzzy Jul 21, 2022
940e2b1
BufferedProcess: Fix internal call
weefuzzy Jul 21, 2022
63662ec
Allocatorize TransientClient + ARModel
weefuzzy Jul 21, 2022
5c845ae
FluidTensor: Make constructors nicer with allocator
weefuzzy Jul 24, 2022
6591ffe
ScopedEigenMap: fix moveability
weefuzzy Jul 24, 2022
cf92bf9
BufferedProcess: Fix setup calls
weefuzzy Jul 24, 2022
9898959
Sink/Source: get rid of pointless view (for now)
weefuzzy Jul 24, 2022
817ebe5
MemoryBufferAdaptor: better constructor for internal FluidTensor
weefuzzy Jul 24, 2022
71c4ea4
TransientClient: Better FluidTensor constructor
weefuzzy Jul 24, 2022
b1580c7
Transients, ARModel: Allocator-ize
weefuzzy Jul 24, 2022
635cdac
Chroma: top corner of matrix, not bottom
weefuzzy Jul 24, 2022
285630d
Pitch: Allocatorize
weefuzzy Jul 24, 2022
d15251e
Loudness: Allocatorize (+ TruePeak)
weefuzzy Jul 24, 2022
55fc494
MelBands, MFCC: Allocatorize
weefuzzy Jul 24, 2022
272c8fd
NMFFilter/Match: Allocatorize
weefuzzy Jul 24, 2022
dc4ce2a
ChromaClient:Nicer FluidTensor constructor
weefuzzy Jul 24, 2022
ca9d967
OnsetClient: Nicer FluidTensor constructor
weefuzzy Jul 24, 2022
05ac221
Default allocator for algos
weefuzzy Jul 24, 2022
354cca5
TransientSlice: Allocatorize
weefuzzy Jul 24, 2022
d1cefba
AmpGate: Allocatorize
weefuzzy Jul 24, 2022
c2026d5
AmpSlice: update client sigs, tidy algos
weefuzzy Jul 24, 2022
c065603
SpectralShape: Allocatorize
weefuzzy Jul 24, 2022
79abad3
Sines: Allocatorize
weefuzzy Jul 25, 2022
9775419
Sines: Formatting
weefuzzy Jul 25, 2022
099c6d3
AudioTransport: Allocatorize
weefuzzy Jul 25, 2022
951d198
NoveltySlice: Allocatorize
weefuzzy Jul 25, 2022
ff483f4
NMFMorph: Allocatorize
weefuzzy Jul 25, 2022
4659c82
AmpFeature:: Allocatorize
weefuzzy Jul 26, 2022
f901d15
NoveltyFeature: Allocatorize
weefuzzy Jul 26, 2022
6f20516
OnsetFeature: Allocatorize
weefuzzy Jul 26, 2022
ec00c69
Get tests to build again
weefuzzy Jul 26, 2022
0ddf03c
Make everything build again, mop up warnings
weefuzzy Jul 27, 2022
1461624
Get Buf wrapped descriptors working again
weefuzzy Jul 27, 2022
0403eaa
ScopedEigenMap: Add expression constructor
weefuzzy Jul 28, 2022
4237988
MedianFilter: fix
weefuzzy Jul 28, 2022
9d3dff4
Novelty: Zap rogue heap allocation
weefuzzy Jul 28, 2022
05f778e
NRTWrapper: Correct frame count and format
weefuzzy Jul 28, 2022
558ce44
ODFs: Allocatorize ODF function lookup, small repairs to algo
weefuzzy Jul 28, 2022
d6214c6
DataScalers: no allocation needed in`transformPoint`
weefuzzy Jul 31, 2022
e95ce05
KMeans: Allocatorize
weefuzzy Jul 31, 2022
d6ba253
ScopedEigenMap: `MatrixBase` constructor for avoiding temoraries in m…
weefuzzy Jul 31, 2022
986d74a
PCA: Allocatorize
weefuzzy Jul 31, 2022
9fb0e99
MLP: Allocatorize
weefuzzy Jul 31, 2022
50b8626
KDTree: Allocatorize
weefuzzy Jul 31, 2022
3fd01a3
KNNRegress/Classify: Allocatorize
weefuzzy Jul 31, 2022
e14a83a
MLPClassifierClient: Rogue string allocation
weefuzzy Jul 31, 2022
7f6919a
KNNClassify/Regress: Make sure allocator is used
weefuzzy Aug 1, 2022
88f431f
UMAP: Allocatorize
weefuzzy Aug 1, 2022
6baea52
Mop up (nearly all) hidden temporaries
weefuzzy Aug 4, 2022
af267d1
Updates for string types in params and messages
weefuzzy Aug 10, 2022
0f9952b
NMFClient: New RatioMask constructor
weefuzzy Aug 10, 2022
90399ed
CMake: Add FMT library
weefuzzy Aug 10, 2022
5823750
FluidTensor: remember to deconst T for container
weefuzzy Aug 10, 2022
2645380
SharedInstance: using string_view hash to keep libstdc++ happy
weefuzzy Aug 11, 2022
529420e
CMake: exclude foonathan::memory from ALL
weefuzzy Aug 11, 2022
1ae64f0
SharedInstance adaptor: correct string type for cusomt alloc
weefuzzy Sep 20, 2022
0c35146
Result: const overload `value()`
weefuzzy Sep 20, 2022
aa194ef
FallbackAlloctor: proper forwarding
weefuzzy Sep 20, 2022
edb9ea7
CMake: Turn off foonathan-memory extras
weefuzzy Sep 27, 2022
4de1364
Merge remote-tracking branch 'origin/dev' into enhance/rtalloc
weefuzzy Sep 27, 2022
2dd453a
TestTransientSlice: Use approval tests for real material
weefuzzy Sep 27, 2022
e45042f
JSON dep: update to fix windows CMake configure
weefuzzy Sep 27, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 37 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,25 @@ FetchContent_Declare(
GIT_PROGRESS TRUE
)

#see https://json.nlohmann.me/integration/cmake/#fetchcontent
FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.11.2/json.tar.xz)
set(JSON_SystemInclude ON CACHE BOOL "")

FetchContent_Declare(
json
GIT_SHALLOW TRUE
# GIT_REPOSITORY https://github.com/nlohmann/json.git
# advice on nlohmann repo is to use this mirror unless we really want ~150 meg of test data as well as headers:
GIT_REPOSITORY https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent
Memory
GIT_SHALLOW TRUE
GIT_REPOSITORY https://github.com/foonathan/memory.git
GIT_PROGRESS TRUE
GIT_TAG v3.10.5
GIT_TAG main
)

FetchContent_Declare(
fmt
GIT_SHALLOW TRUE
GIT_REPOSITORY https://github.com/fmtlib/fmt
GIT_PROGRESS TRUE
GIT_TAG master
)
set(JSON_SystemInclude ON CACHE BOOL "")

if(HISS_PATH) #if hiss path is set, this will stop it downloading
get_filename_component(FETCHCONTENT_SOURCE_DIR_HISSTOOLS ${HISS_PATH} ABSOLUTE)
Expand Down Expand Up @@ -139,6 +148,18 @@ endif()

add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)

set(FOONATHAN_MEMORY_BUILD_TOOLS OFF CACHE BOOL "" FORCE)
set(FOONATHAN_MEMORY_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(FOONATHAN_MEMORY_BUILD_TESTS OFF CACHE BOOL "" FORCE)

FetchContent_GetProperties(Memory)
if(NOT memory_POPULATED)
FetchContent_Populate(Memory)
endif()
add_subdirectory(${memory_SOURCE_DIR} ${memory_BINARY_DIR} EXCLUDE_FROM_ALL)

FetchContent_MakeAvailable(fmt)

# HISSTools FFT target
add_library(
HISSTools_FFT STATIC "${hisstools_SOURCE_DIR}/HISSTools_FFT/HISSTools_FFT.cpp"
Expand Down Expand Up @@ -184,13 +205,17 @@ target_include_directories(
"${eigen_SOURCE_DIR}"
"${spectra_SOURCE_DIR}/include"
"${hisstools_SOURCE_DIR}"
"${memory_SOURCE_DIR}/include/foonathan"
"${fmt_SOURCE_DIR}/include"
)
target_link_libraries(
FLUID_DECOMPOSITION INTERFACE
HISSTools_FFT
flucoma_VERSION_LIB
tl::optional
nlohmann_json::nlohmann_json
foonathan_memory
fmt::fmt
)
target_sources(
FLUID_DECOMPOSITION INTERFACE ${HEADERS}
Expand Down Expand Up @@ -225,9 +250,14 @@ if(DEFINED FLUID_ARCH)
endif()

#Examples

option(BUILD_EXAMPLES "Build C++ example code (off by default)" OFF)

if(BUILD_EXAMPLES)
add_subdirectory(
"${CMAKE_CURRENT_SOURCE_DIR}/examples"
)
endif()

enable_testing()

Expand Down
162 changes: 93 additions & 69 deletions include/algorithms/public/AudioTransport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ under the European Union’s Horizon 2020 research and innovation programme
#include "../util/FFT.hpp"
#include "../util/FluidEigenMappings.hpp"
#include "../../data/FluidIndex.hpp"
#include "../../data/FluidMemory.hpp"
#include "../../data/TensorTypes.hpp"
#include <Eigen/Core>
#include <cmath>
Expand All @@ -41,77 +42,88 @@ class AudioTransport
using ArrayXcd = Eigen::ArrayXcd;
template <typename T>
using Ref = Eigen::Ref<T>;
using TransportMatrix = std::vector<std::tuple<index, index, double>>;
using TransportMatrix = rt::vector<std::tuple<index, index, double>>;
template <typename T>
using vector = std::vector<T>;
using vector = rt::vector<T>;

public:
AudioTransport(index maxFFTSize)
AudioTransport(index maxFFTSize, Allocator& alloc)
: mWindowSize(maxFFTSize), mFFTSize(maxFFTSize),
mBins(maxFFTSize / 2 + 1), mFFT(maxFFTSize),
mSTFT(maxFFTSize, maxFFTSize, maxFFTSize / 2),
mISTFT(maxFFTSize, maxFFTSize, maxFFTSize / 2),
mReassignSTFT(maxFFTSize, maxFFTSize, maxFFTSize / 2)
mReassignSTFT(maxFFTSize, maxFFTSize, maxFFTSize / 2,
static_cast<index>(WindowFuncs::WindowTypes::kHannD)),
mBinFreqs(maxFFTSize / 2 + 1, alloc), mWindow(maxFFTSize, alloc),
mWindowSquared(maxFFTSize, alloc), mPhase(maxFFTSize / 2 + 1, alloc),
mPhaseDiff(maxFFTSize / 2 + 1, alloc),
mChanged(maxFFTSize / 2 + 1, alloc)
{}

void init(index windowSize, index fftSize, index hopSize)
{
mWindowSize = windowSize;
mWindow = ArrayXd::Zero(mWindowSize);
WindowFuncs::map()[WindowFuncs::WindowTypes::kHann](mWindowSize, mWindow);
mWindow.head(mWindowSize).setZero();
WindowFuncs::map()[WindowFuncs::WindowTypes::kHann](
mWindowSize, mWindow.head(mWindowSize));
mWindowSquared = mWindow * mWindow;
mFFTSize = fftSize;
mHopSize = hopSize;
mBins = fftSize / 2 + 1;
mPhase = ArrayXd::Zero(mBins);
mChanged = ArrayXi::Zero(mBins);
mBinFreqs = ArrayXd::LinSpaced(mBins, 0, mBins - 1) * (2 * pi) / mFFTSize;
mPhaseDiff = mBinFreqs * mHopSize;
mSTFT = STFT(windowSize, fftSize, hopSize);
mISTFT = ISTFT(windowSize, fftSize, hopSize);
mReassignSTFT = STFT(windowSize, fftSize, hopSize,
static_cast<index>(WindowFuncs::WindowTypes::kHannD));
mPhase.setZero();
mChanged.setZero();
mBinFreqs.head(mBins) =
ArrayXd::LinSpaced(mBins, 0, mBins - 1) * (2 * pi) / mFFTSize;
mPhaseDiff.head(mBins) = mBinFreqs * mHopSize;
mSTFT.resize(windowSize, fftSize, hopSize);
mISTFT.resize(windowSize, fftSize, hopSize);
mReassignSTFT.resize(windowSize, fftSize, hopSize);
mFFT.resize(fftSize);
mInitialized = true;
}

bool initialized() const { return mInitialized; }

void processFrame(RealVectorView in1, RealVectorView in2, double weight,
RealMatrixView out)
RealMatrixView out, Allocator& alloc)
{
using namespace _impl;
using namespace Eigen;
assert(mInitialized);
ArrayXd frame1 = asEigen<Array>(in1);
ArrayXd frame2 = asEigen<Array>(in2);
ArrayXcd spectrum1(mBins);
ArrayXcd spectrum1Dh(mBins);
ArrayXcd spectrum2(mBins);
ArrayXcd spectrum2Dh(mBins);
ArrayXd output(frame1.size());
ScopedEigenMap<ArrayXd> frame1(in1.size(), alloc);
frame1 = asEigen<Array>(in1);
ScopedEigenMap<ArrayXd> frame2(in2.size(), alloc);
frame2 = asEigen<Array>(in2);
ScopedEigenMap<ArrayXcd> spectrum1(mBins, alloc);
ScopedEigenMap<ArrayXcd> spectrum1Dh(mBins, alloc);
ScopedEigenMap<ArrayXcd> spectrum2(mBins, alloc);
ScopedEigenMap<ArrayXcd> spectrum2Dh(mBins, alloc);
ScopedEigenMap<ArrayXd> output(frame1.size(), alloc);
mSTFT.processFrame(frame1, spectrum1);
mReassignSTFT.processFrame(frame1, spectrum1Dh);
mSTFT.processFrame(frame2, spectrum2);
mReassignSTFT.processFrame(frame2, spectrum2Dh);
ArrayXcd result =
interpolate(spectrum1, spectrum1Dh, spectrum2, spectrum2Dh, weight);
ScopedEigenMap<ArrayXcd> result = interpolate(
spectrum1, spectrum1Dh, spectrum2, spectrum2Dh, weight, alloc);
mISTFT.processFrame(result, output);
out.row(0) <<= asFluid(output);
out.row(1) <<= asFluid(mWindowSquared);
_impl::asEigen<Array>(out.row(0)) = output;
_impl::asEigen<Array>(out.row(1)) = mWindowSquared.head(mWindowSize);
}

vector<SpetralMass> segmentSpectrum(const Ref<ArrayXd> mag,
const Ref<ArrayXd> reasignedFreq)
const Ref<ArrayXd> reasignedFreq,
Allocator& alloc)
{

vector<SpetralMass> masses;
double totalMass = mag.sum() + epsilon;
ArrayXi sign = (reasignedFreq > mBinFreqs).cast<int>();
vector<SpetralMass> masses(alloc);
double totalMass = mag.sum() + epsilon;
ScopedEigenMap<ArrayXi> sign(reasignedFreq.size(), alloc);
sign = (reasignedFreq > mBinFreqs.head(reasignedFreq.size())).cast<int>();
mChanged.setZero();
mChanged.segment(1, mBins - 1) =
sign.segment(1, mBins - 1) - sign.segment(0, mBins - 1);
SpetralMass currentMass{0, 0, 0, 0};
for (index i = 1; i < mChanged.size(); i++)
for (index i = 1; i < mBins; i++)
{
if (mChanged(i) == -1)
{
Expand All @@ -137,10 +149,11 @@ class AudioTransport
return masses;
}

TransportMatrix computeTransportMatrix(std::vector<SpetralMass> m1,
std::vector<SpetralMass> m2)
TransportMatrix computeTransportMatrix(rt::vector<SpetralMass>& m1,
rt::vector<SpetralMass>& m2,
Allocator& alloc)
{
TransportMatrix matrix;
TransportMatrix matrix(alloc);
index index1 = 0, index2 = 0;
double mass1 = m1[0].mass;
double mass2 = m2[0].mass;
Expand Down Expand Up @@ -186,41 +199,52 @@ class AudioTransport
}
}

ArrayXcd interpolate(Ref<ArrayXcd> in1, Ref<ArrayXcd> in1Dh,
Ref<ArrayXcd> in2, Ref<ArrayXcd> in2Dh,
double interpolation)
ScopedEigenMap<ArrayXcd> interpolate(Ref<ArrayXcd> in1, Ref<ArrayXcd> in1Dh,
Ref<ArrayXcd> in2, Ref<ArrayXcd> in2Dh,
double interpolation, Allocator& alloc)
{
ArrayXd mag1 = in1.abs().real();
ArrayXd mag2 = in2.abs().real();
ArrayXcd result = ArrayXcd::Zero(mBins);
double mag1Sum = mag1.sum();
double mag2Sum = mag2.sum();
ScopedEigenMap<ArrayXd> mag1(in1.size(), alloc);
mag1 = in1.abs().real();
ScopedEigenMap<ArrayXd> mag2(in2.size(), alloc);
mag2 = in2.abs().real();
ScopedEigenMap<ArrayXcd> result(mBins, alloc);
result.setZero();
double mag1Sum = mag1.sum();
double mag2Sum = mag2.sum();
if (mag1Sum <= 0 && mag2Sum <= 0) { return result; }
else if (mag1Sum > 0 && mag2Sum <= 0)
{
return in1;
result = in1;
return result;
}
else if (mag1Sum <= 0 && mag2Sum > 0)
{
return in2;
result = in2;
return result;
}
ArrayXd phase1 = in1.arg().real();
ArrayXd phase2 = in2.arg().real();
ArrayXd reasignedW1 = mBinFreqs - (in1Dh / in1).imag();
ArrayXd reasignedW2 = mBinFreqs - (in2Dh / in2).imag();
ArrayXd newAmplitudes = ArrayXd::Zero(mBins);
ArrayXd newPhases = ArrayXd::Zero(mBins);
std::vector<SpetralMass> s1 = segmentSpectrum(mag1, reasignedW1);
std::vector<SpetralMass> s2 = segmentSpectrum(mag2, reasignedW2);
ScopedEigenMap<ArrayXd> phase1(in1.size(), alloc);
phase1 = in1.arg().real();
ScopedEigenMap<ArrayXd> phase2(in2.size(), alloc);
phase2 = in2.arg().real();
ScopedEigenMap<ArrayXd> reasignedW1(in1.size(), alloc);
reasignedW1 = mBinFreqs.head(in1.size()) - (in1Dh / in1).imag();
ScopedEigenMap<ArrayXd> reasignedW2(in2.size(), alloc);
reasignedW2 = mBinFreqs.head(in2.size()) - (in2Dh / in2).imag();
ScopedEigenMap<ArrayXd> newAmplitudes(mBins, alloc);
newAmplitudes.setZero();
ScopedEigenMap<ArrayXd> newPhases(mBins, alloc);
newPhases.setZero();
rt::vector<SpetralMass> s1 = segmentSpectrum(mag1, reasignedW1, alloc);
rt::vector<SpetralMass> s2 = segmentSpectrum(mag2, reasignedW2, alloc);
if (s1.size() == 0 || s2.size() == 0) { return result; }

TransportMatrix matrix = computeTransportMatrix(s1, s2);
TransportMatrix matrix = computeTransportMatrix(s1, s2, alloc);
for (auto t : matrix)
{
SpetralMass m1 = s1[asUnsigned(std::get<0>(t))];
SpetralMass m2 = s2[asUnsigned(std::get<1>(t))];
index interpolatedBin = std::lrint((1 - interpolation) * m1.centerBin +
interpolation * m2.centerBin);
interpolation * m2.centerBin);
double interpolationFactor = interpolation;
if (m1.centerBin != m2.centerBin)
{
Expand All @@ -243,21 +267,21 @@ class AudioTransport
return result;
}

index mWindowSize{1024};
index mHopSize{512};
ArrayXd mBinFreqs;
ArrayXd mWindow;
ArrayXd mWindowSquared;
index mFFTSize{1024};
index mBins{513};
FFT mFFT;
bool mInitialized{false};
ArrayXd mPhase;
ArrayXd mPhaseDiff;
ArrayXi mChanged;
STFT mSTFT;
ISTFT mISTFT;
STFT mReassignSTFT;
index mWindowSize{1024};
index mHopSize{512};
index mFFTSize{1024};
index mBins{513};
FFT mFFT;
STFT mSTFT;
ISTFT mISTFT;
STFT mReassignSTFT;
bool mInitialized{false};
ScopedEigenMap<ArrayXd> mBinFreqs;
ScopedEigenMap<ArrayXd> mWindow;
ScopedEigenMap<ArrayXd> mWindowSquared;
ScopedEigenMap<ArrayXd> mPhase;
ScopedEigenMap<ArrayXd> mPhaseDiff;
ScopedEigenMap<ArrayXi> mChanged;
};
} // namespace algorithm
} // namespace fluid
Loading