From 519fd46f2a27714b4b31c10c7b2b9676401a1779 Mon Sep 17 00:00:00 2001 From: Owen Green Date: Sun, 16 Sep 2018 17:01:39 +0100 Subject: [PATCH] Add NRT novelty segmentation --- .../Classes/FluidBufNoveltySlice.sc | 13 ++++ src/FluidBufNoveltySlice/CMakeLists.txt | 20 ++++++ .../FluidBufNoveltySlice.cpp | 71 +++++++++++++++++++ src/FluidBufNoveltySlice/tests.scd | 71 +++++++++++++++++++ 4 files changed, 175 insertions(+) create mode 100644 release-packaging/Classes/FluidBufNoveltySlice.sc create mode 100755 src/FluidBufNoveltySlice/CMakeLists.txt create mode 100644 src/FluidBufNoveltySlice/FluidBufNoveltySlice.cpp create mode 100644 src/FluidBufNoveltySlice/tests.scd diff --git a/release-packaging/Classes/FluidBufNoveltySlice.sc b/release-packaging/Classes/FluidBufNoveltySlice.sc new file mode 100644 index 0000000..fd38649 --- /dev/null +++ b/release-packaging/Classes/FluidBufNoveltySlice.sc @@ -0,0 +1,13 @@ +FluidBufNoveltySlice{ + *process { arg server, src, offsetframes = 0, numframes = -1, offsetchans = 0, numchans = -1, transbuf, kernelsize = 3, threshold = 0.8, winsize = 1024, hopsize = 512, fftsize = 2048; + + server = server ? Server.default; + if(src.isNil) {Error("Invalid Source Buffer").format(thisMethod.name, this.class.name).throw}; + if(transbuf.isNil) {Error("Invalid Slices Buffer").format(thisMethod.name, this.class.name).throw}; + server.sendMsg(\cmd, \BufNoveltySlice, src, offsetframes, numframes, offsetchans, numchans, +transbuf, kernelsize, threshold, winsize, hopsize, fftsize); + + + +} +} \ No newline at end of file diff --git a/src/FluidBufNoveltySlice/CMakeLists.txt b/src/FluidBufNoveltySlice/CMakeLists.txt new file mode 100755 index 0000000..3693881 --- /dev/null +++ b/src/FluidBufNoveltySlice/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/FluidBufNoveltySlice/FluidBufNoveltySlice.cpp b/src/FluidBufNoveltySlice/FluidBufNoveltySlice.cpp new file mode 100644 index 0000000..3c348a0 --- /dev/null +++ b/src/FluidBufNoveltySlice/FluidBufNoveltySlice.cpp @@ -0,0 +1,71 @@ + // FD_BufNMF, an NRT buffer NMF Processor +// 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 "clients/nrt/NoveltyClient.hpp" +#include "fdNRTBase.hpp" +#include "data/FluidTensor.hpp" +#include "clients/common/FluidParams.hpp" +//#include "SC_PlugIn.h" +//#include +//#include + +static InterfaceTable *ft; + +namespace fluid { + namespace sc{ + + class BufNoveltySlice: public NRTCommandBase + { + public: + using client_type = segmentation::NoveltyClient; + using NRTCommandBase::NRTCommandBase; + + ~BufNoveltySlice() {} + + void runCommand(World* world, void* replyAddr, char* completionMsgData, size_t completionMsgSize) + { + cmd(world, "/BufNoveltySlice", replyAddr, completionMsgData, completionMsgSize); + } + + bool process(World* world) + { + //sanity check the parameters + bool parametersOk; + client_type::ProcessModel processModel; + std::string whatHappened;//this will give us a message to pass back if param check fails + std::tie(parametersOk,whatHappened,processModel) = trans.sanityCheck(); + if(!parametersOk) + { + Print("FluidBufNovletySlice: %s \n", whatHappened.c_str()); + return false; + } + trans.process(processModel); + mModel = processModel; + return true; + } + + bool postProcess(World* world) + { + static_cast(mModel.indices)->assignToRT(world); + return true; + } + + bool postComplete(World* w) { return true; } + std::vector& parameters() + { + return trans.getParams(); + } + private: + client_type trans; + client_type::ProcessModel mModel; + };//class + } //namespace sc +}//namespace fluid + + +PluginLoad(OfflineFluidDecompositionUGens) { + ft = inTable; + registerCommand(ft, "BufNoveltySlice"); + fluid::sc::printCmd(ft,"BufNoveltySlice","FluidBufNoveltySlice"); +} diff --git a/src/FluidBufNoveltySlice/tests.scd b/src/FluidBufNoveltySlice/tests.scd new file mode 100644 index 0000000..4440398 --- /dev/null +++ b/src/FluidBufNoveltySlice/tests.scd @@ -0,0 +1,71 @@ +s.reboot +//////////////////////////// +// test for efficiency + +( +b = Buffer.read(s,"/Users/owen/Box Sync/FluCoMa/Temporary/GLRSegmentation/SegmentationExample.wav"); +c = Buffer.new(s); +) +b.query +( +// with basic params +Routine{ + t = Main.elapsedTime; + FluidBufNoveltySlice.process(s,b.bufnum, transbuf:c.bufnum, threshold:0.5); + s.sync; + (Main.elapsedTime - t).postln; +}.play +); + +//check the number of slices +c.query; + +//loops over a splice +( +{ + BufRd.ar( + 1, + b.bufnum, + Phasor.ar( + 0, + 1, + BufRd.kr( + 1, + c.bufnum, + MouseX.kr( + 0, + BufFrames.kr(c.bufnum) - 1), + 0, + 1), + BufRd.kr( + 1, + c.bufnum, + MouseX.kr( + 1, + BufFrames.kr(c.bufnum)), + 0, + 1), + BufRd.kr( + 1, + c.bufnum, + MouseX.kr( + 0, + BufFrames.kr(c.bufnum) - 1), + 0, + 1)), + 0, + 1) +}.play; +) + + +// with everything changed to make it much faster +( +Routine{ + t = Main.elapsedTime; + FluidBufNoveltySlice.process(s,b.bufnum, 44100, 44100, 0, 0, c.bufnum, d.bufnum, 100, 512,256,1,2,1,12,20); + s.sync; + (Main.elapsedTime - t).postln; +}.play +); +