From af1c7e09927f65813c6c127bb8ff1523b7d4915d Mon Sep 17 00:00:00 2001 From: Owen Green Date: Wed, 12 Sep 2018 15:40:57 +0100 Subject: [PATCH] Add real time transient detector --- release-packaging/Classes/FluidTransients.sc | 14 ++ src/FluidTransients/CMakeLists.txt | 20 +++ src/FluidTransients/FluidTransients.cpp | 130 +++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 release-packaging/Classes/FluidTransients.sc create mode 100755 src/FluidTransients/CMakeLists.txt create mode 100644 src/FluidTransients/FluidTransients.cpp diff --git a/release-packaging/Classes/FluidTransients.sc b/release-packaging/Classes/FluidTransients.sc new file mode 100644 index 0000000..ef245f6 --- /dev/null +++ b/release-packaging/Classes/FluidTransients.sc @@ -0,0 +1,14 @@ +FluidTransients : MultiOutUGen { + *ar { arg in = 0, order = 20, blocksize = 256, padding = 128, skew = 0.0, threshFwd = 3.0, threshBack = 1.1, winSize=14, debounce=25; + ^this.multiNew('audio', in.asAudioRateInput(this), order, blocksize, padding, skew,threshFwd ,threshBack, winSize) + } + init { arg ... theInputs; + inputs = theInputs; + channels = [ + OutputProxy(rate, this, 0), + OutputProxy(rate, this, 1) + ]; + ^channels + } + checkInputs { ^this.checkNInputs(1) } +} \ No newline at end of file diff --git a/src/FluidTransients/CMakeLists.txt b/src/FluidTransients/CMakeLists.txt new file mode 100755 index 0000000..3693881 --- /dev/null +++ b/src/FluidTransients/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.3) +get_filename_component(PLUGIN ${CMAKE_CURRENT_LIST_DIR} NAME_WE) +message("Configuring ${PLUGIN}") +set(FILENAME ${PLUGIN}.cpp) + +add_library( + ${PLUGIN} + MODULE + ${FILENAME} +) + +target_include_directories( + ${PLUGIN} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../../include +) + +target_link_libraries( + ${PLUGIN} PRIVATE FLUID_DECOMPOSITION +) + +include(${CMAKE_CURRENT_LIST_DIR}/../../scripts/target_post.cmake) diff --git a/src/FluidTransients/FluidTransients.cpp b/src/FluidTransients/FluidTransients.cpp new file mode 100644 index 0000000..11fb17c --- /dev/null +++ b/src/FluidTransients/FluidTransients.cpp @@ -0,0 +1,130 @@ + +// A tool from the FluCoMa project, funded by the European Research Council (ERC) under the European Union’s Horizon 2020 research and innovation programme (grant agreement No 725899) + +#include "SC_PlugIn.hpp" +#include "data/FluidTensor.hpp" +#include "clients/rt/TransientClient.hpp" + +static InterfaceTable *ft; +namespace fluid { +namespace stn{ + class FluidTransients: public SCUnit + { + using AudioSignalWrapper = stn::TransientsClient::AudioSignal; + using SignalWrapper = stn::TransientsClient::Signal; + + // using SignalPointer = std::unique_ptr; + public: + FluidTransients() + { + //Order of args + //Window size, Hop size, FFT Size + + //Get the window size + + +// const float hfilter_size = in0(1); +// const float pfilter_size = in0(2); +// const float window_size = in0(3); +// const float hop_size = in0(4); +// const float fft_size = in0(5); +// + + //Oh NO! Heap allocation! Make client object + m_client = new stn::TransientsClient(65536); + setParams(true); + +// m_client->getParams()[0].setLong(pfilter_size); +// m_client->getParams()[1].setLong(hfilter_size); +// m_client->getParams()[2].setLong(window_size); +// m_client->getParams()[3].setLong(hop_size); +// m_client->getParams()[4].setLong(fft_size); + + bool isOK; + std::string feedback; + + std::tie(isOK, feedback) = m_client->sanityCheck(); + if(!isOK) + { + Print("fdRTHPSS Error: %s",feedback.c_str()); + return; + } + + + m_client->set_host_buffer_size(bufferSize()); + m_client->reset(); + + //Work out what signals we need. For now keep it simple: + //in 0 => only audio + //out 0 => only audio + input_signals[0] = new AudioSignalWrapper(); + output_signals[0] = new AudioSignalWrapper(); + output_signals[1] = new AudioSignalWrapper(); + + mCalcFunc = make_calc_function(); + Unit* unit = this; + ClearUnitOutputs(unit,1); + } + + ~FluidTransients() + { + delete input_signals[0]; + delete output_signals[0]; + delete output_signals[1]; + delete m_client; + } + + private: + + void setParams(bool instantiation) + { + assert(m_client); + for(size_t i = 0; i < m_client->getParams().size(); ++i) + { + parameter::Instance& p = m_client->getParams()[i]; + + if(!instantiation && p.getDescriptor().instatiation()) + continue; + + switch(p.getDescriptor().getType()) + { + case parameter::Type::Long: + p.setLong(in0(i+1)); + p.checkRange(); + break; + case parameter::Type::Float: + p.setFloat(in0(i+1)); + p.checkRange(); + break; + case parameter::Type::Buffer: +// p.setBuffer( in0(i+1)); + break; + default: + break; + } + } + } + + + void next(int numsamples) + { + setParams(false); + const float* input = in(0); + const float inscalar = in0(0); + input_signals[0]->set(const_cast(input), inscalar); + output_signals[0]->set(out(0), out0(0)); + output_signals[1]->set(out(1), out0(1)); + m_client->do_process(std::begin(input_signals),std::end(input_signals),std::begin(output_signals), std::end(output_signals),numsamples,1,2); + } + + stn::TransientsClient* m_client; + SignalWrapper* input_signals[1]; + SignalWrapper* output_signals[2]; + }; +} +} + +PluginLoad(FluidSTFTUGen) { + ft = inTable; + registerUnit(ft, "FluidTransients"); +}