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
2 changes: 1 addition & 1 deletion .github/workflows/flucoma-core-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ jobs:

- name: Test
working-directory: ${{github.workspace}}/build
run: ctest -C ${{env.BUILD_TYPE}}
run: ctest -C ${{env.BUILD_TYPE}} -j3

1 change: 1 addition & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.received.*
24 changes: 24 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
cmake_minimum_required (VERSION 3.11)

###### Utils
add_subdirectory(test_signals)

##### Assert Death Testing

Expand Down Expand Up @@ -131,6 +132,23 @@ add_test_executable(TestFluidSource clients/common/TestFluidSource.cpp)
add_test_executable(TestFluidSink clients/common/TestFluidSink.cpp)
add_test_executable(TestBufferedProcess clients/common/TestBufferedProcess.cpp)

add_test_executable(TestNoveltySeg
algorithms/public/TestNoveltySegmentation.cpp
)
add_test_executable(TestOnsetSeg algorithms/public/TestOnsetSegmentation.cpp)
add_test_executable(TestEnvelopeSeg algorithms/public/TestEnvelopeSegmentation.cpp)

add_test_executable(TestEnvelopeGate algorithms/public/TestEnvelopeGate.cpp)

add_test_executable(TestTransientSlice algorithms/public/TestTransientSlice.cpp)


target_link_libraries(TestNoveltySeg PRIVATE TestSignals)
target_link_libraries(TestOnsetSeg PRIVATE TestSignals)
target_link_libraries(TestEnvelopeSeg PRIVATE TestSignals)
target_link_libraries(TestEnvelopeGate PRIVATE TestSignals)
target_link_libraries(TestTransientSlice PRIVATE TestSignals)

include(CTest)
include(Catch)

Expand All @@ -145,6 +163,12 @@ 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(TestNoveltySeg WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
catch_discover_tests(TestOnsetSeg WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
catch_discover_tests(TestEnvelopeSeg WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
catch_discover_tests(TestEnvelopeGate WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
catch_discover_tests(TestTransientSlice 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}")
Expand Down
76 changes: 76 additions & 0 deletions tests/algorithms/public/SlicerTestHarness.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#pragma once

#include <algorithms/public/STFT.hpp>
#include <data/FluidTensor.hpp>
#include <algorithm>
#include <complex>
#include <vector>

namespace fluid {

template <typename PrepareSlicerFn, typename MakeInputsFn,
typename InvokeSlicerFn, typename Params>
std::vector<index>
SlicerTestHarness(FluidTensorView<const double, 1> testSignal, Params p,
PrepareSlicerFn&& prepareSlicer, MakeInputsFn&& makeInputs,
InvokeSlicerFn&& invokeSlicer, index addedLatency)
{
const index halfWindow = p.window; // >> 1;
const index padding = addedLatency;
FluidTensor<double, 1> padded(p.window + halfWindow + padding +
testSignal.size());
padded.fill(0);
padded(Slice(halfWindow, testSignal.size())) = testSignal;
const fluid::index nHops =
std::floor<index>((padded.size() - p.window) / p.hop);
auto slicer = prepareSlicer(p);
std::vector<index> spikePositions;
for (index i = 0; i < nHops; ++i)
{
auto input = makeInputs(padded(Slice(i * p.hop, p.window)));
if (invokeSlicer(slicer, input, p) > 0)
{
spikePositions.push_back((i * p.hop) - padding - p.hop);
}
}

// This reproduces what the NRT wrapper does (and hence the result that the
// existing test in SC sees). I'm dubious that
// it really ought to be needed though. I think we're adjusting the latency
// by a hop too much
std::transform(spikePositions.begin(), spikePositions.end(),
spikePositions.begin(),
[&p](index x) { return std::max<index>(0, x); });

spikePositions.erase(
std::unique(spikePositions.begin(), spikePositions.end()),
spikePositions.end());

return spikePositions;
}


struct STFTMagnitudeInput
{

template <typename Params>
STFTMagnitudeInput(const Params& p)
: mSTFT(index(p.window), index(p.fft), index(p.hop)),
mSTFTFrame((index(p.fft) / 2) + 1), mMagnitudes((index(p.fft) / 2) + 1)
{}

FluidTensorView<const double, 1> operator()(FluidTensorView<double, 1> source)
{
mSTFT.processFrame(source, mSTFTFrame);
mSTFT.magnitude(mSTFTFrame, mMagnitudes);
return FluidTensorView<const double, 1>(mMagnitudes);
}

private:
algorithm::STFT mSTFT;
FluidTensor<std::complex<double>, 1> mSTFTFrame;
FluidTensor<double, 1> mMagnitudes;
};


} // namespace fluid
Loading