Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ target_link_libraries(TestFluidTensorDeath PRIVATE
add_test_executable(TestFluidTensorView data/TestFluidTensorView.cpp)
add_test_executable(TestFluidTensorSupport data/TestFluidTensorSupport.cpp)
add_test_executable(TestFluidDataSet data/TestFluidDataSet.cpp)
add_test_executable(TestFluidSource clients/common/TestFluidSource.cpp)
add_test_executable(TestFluidSink clients/common/TestFluidSink.cpp)
add_test_executable(TestBufferedProcess clients/common/TestBufferedProcess.cpp)

include(CTest)
include(Catch)
Expand All @@ -142,4 +145,8 @@ catch_discover_tests(TestFluidTensorView WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
catch_discover_tests(TestFluidTensorSupport WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
catch_discover_tests(TestFluidDataSet WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")

catch_discover_tests(TestFluidSource WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
catch_discover_tests(TestFluidSink WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
catch_discover_tests(TestBufferedProcess WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")

add_compile_tests("FluidTensor Compilation Tests" data/compile_tests/TestFluidTensor_Compile.cpp)
72 changes: 72 additions & 0 deletions tests/clients/common/TestBufferedProcess.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
// #include <catch2/catch_test_macros.hpp>
#include <clients/common/BufferedProcess.hpp>
#include <clients/common/FluidContext.hpp>
#include <data/FluidTensor.hpp>
#include <CatchUtils.hpp>
#include <cmath>
#include <algorithm>
#include <array>
#include <vector>

using fluid::EqualsRange;
using fluid::FluidTensor;
using fluid::FluidTensorView;
using fluid::Slice;
using fluid::client::BufferedProcess;
using fluid::client::FluidContext;

TEST_CASE("BufferedProcess will reconstruct windowed input properly under COLA conditions","[BufferedProcess]"){

BufferedProcess processor;

constexpr int hostSize = 64;
FluidContext c;

auto frameSize = GENERATE(32, 64, 256, 1024, 8192);

auto hop = frameSize / 2;

processor.maxSize(frameSize, frameSize, 1,1 );
processor.hostSize(hostSize); // sigh, FIXME

FluidTensor<double,2> input(1,128 * frameSize);

input(Slice(0),Slice(frameSize)).fill(1);

FluidTensor<double,2> output(1,hostSize);
FluidTensor<double, 2> window(1, frameSize);

std::vector<double> expected(hostSize);
std::vector<double> actual(hostSize);

window.apply([frameSize, i=0](double& x) mutable {
x = 0.5 - 0.5 * cos((2 * M_PI * i++) / frameSize);
}); //generate Hann window

for(int i = frameSize; i < input.size() - hostSize; i+=hostSize)
{
processor.push(input(Slice(0),Slice(i,hostSize)));

//Hann windowing with overlap of 2 should be COLA
processor.process(frameSize, frameSize,hop,c,
[&window](FluidTensorView<double, 2> in, FluidTensorView<double, 2> out) {
out = in;
out.apply(window, [](double& x, double w) { x *= w; });
});

processor.pull(FluidTensorView<double,2>(actual.data(),0,1,hostSize));

//we expect output to be input delayed by frameSize samples
auto expectedSlice= input(Slice(0), Slice(i - frameSize, hostSize));
std::copy(expectedSlice.begin(), expectedSlice.end(),expected.begin());

auto matcher = Catch::Matchers::Approx(expected);
double epsilon = 1e-12;
matcher.epsilon(epsilon);

CHECK_THAT(actual,matcher);

}
}
74 changes: 74 additions & 0 deletions tests/clients/common/TestFluidSink.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
// #include <catch2/catch_test_macros.hpp>
#include <clients/common/FluidSink.hpp>
#include <data/FluidTensor.hpp>
#include <CatchUtils.hpp>
#include <algorithm>
#include <array>
#include <vector>

using fluid::EqualsRange;
using fluid::FluidSink;
using fluid::FluidTensor;
using fluid::FluidTensorView;
using fluid::Slice;


TEMPLATE_TEST_CASE("FluidSink can overlap-add a varitety of window sizes and hops",
"[FluidSink][frames]", int, double)
{

constexpr int hostSize = 64;
constexpr int maxFrameSize = 1024;

FluidSink<TestType> olaBuffer(maxFrameSize, 1);
olaBuffer.setHostBufferSize(hostSize);
olaBuffer.reset(1); // sigh, FIXME

std::array<TestType, 2 * maxFrameSize> data;
data.fill(1);


std::array<TestType, maxFrameSize> emptyFrame;

emptyFrame.fill(0);
// std::iota(data.begin(), data.end(), 0);

// run the test with each of these frame sizes
auto frameSize = GENERATE(32, 43, 64, 96, 128, 512);

FluidTensor<TestType, 1> expected(data.size());
expected.fill(0);
FluidTensor<TestType, 2> output(1, hostSize);


// and for each frame size above, we test with these overlaps
auto overlap = GENERATE(1,2,3,4);

int hop = frameSize / overlap;

//simulate ouptut data by building buffer for whole span
for(int i = 0; i < expected.size();i+=hop)
{
int chunkSize = std::min<int>(frameSize, expected.size() - i);
expected(Slice(i,chunkSize)).apply([](TestType& x){
x += 1;
});
}


for (int i = 0, j = 0, k = 0; i < data.size() - hostSize; i += hostSize)
{

for (; j < hostSize; j += hop, k += 1)
{
auto input = FluidTensorView<TestType, 2>{ data.data(), i, 1, frameSize };
olaBuffer.push(input, j);
}

j = j < hostSize ? j : j - hostSize;
olaBuffer.pull(FluidTensorView<TestType,2>(output));
CHECK_THAT(output,EqualsRange(expected(Slice(i,hostSize))));
}
}
63 changes: 63 additions & 0 deletions tests/clients/common/TestFluidSource.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
// #include <catch2/catch_test_macros.hpp>
#include <clients/common/FluidSource.hpp>
#include <data/FluidTensor.hpp>
#include <CatchUtils.hpp>
#include <algorithm>
#include <array>
#include <vector>

using fluid::EqualsRange;
using fluid::FluidSource;
using fluid::FluidTensor;
using fluid::FluidTensorView;
using fluid::Slice;

TEMPLATE_TEST_CASE(
"FluidSource can provide different window and hop sizes with a known delay",
"[FluidSource][frames]", int, double)
{

constexpr int hostSize = 64;
constexpr int maxFrameSize = 1024;

FluidSource<TestType> framer(maxFrameSize, 1);
framer.setHostBufferSize(hostSize);
framer.reset(1); // sigh, FIXME

std::array<TestType, 2 * maxFrameSize> data;
std::array<TestType, maxFrameSize> output;
// std::array<TestType, maxFrameSize> emptyFrame;

// emptyFrame.fill(0);
std::iota(data.begin(), data.end(), 0);

// run the test with each of these frame sizes
auto frameSize = GENERATE(32, 43, 64, 96, 128, 512);


// and for each frame size above, we test with these hops
auto hop = GENERATE_REF(int(frameSize / 4), int(frameSize / 3),
int(frameSize / 2), int(frameSize));


FluidTensor<TestType, 1> expected(data.size() + frameSize);
expected(Slice(frameSize)) = FluidTensorView<TestType,1>(data.data(),0,data.size());

for (int i = 0, j = 0, k = 0; i < data.size() - hostSize; i += hostSize)
{
auto input = FluidTensorView<TestType, 2>{ data.data(), i, 1, hostSize };
framer.push(input);
auto outputView = FluidTensorView<TestType, 2>{ output.data(), 0, 1, frameSize };


for (; j < hostSize; j += hop, k += hop)
{
framer.pull(outputView, j);
CHECK_THAT(outputView, EqualsRange(expected(Slice(k,frameSize))));
}

j = j < hostSize ? j : j - hostSize;
}
}