From a39f75e241a717ccd271f00c1a444088b1ce0468 Mon Sep 17 00:00:00 2001 From: Owen Green Date: Tue, 28 Aug 2018 10:12:14 +0100 Subject: [PATCH] fdNRTBase: Base wrapper class for Async commands --- fdNRTBase/CMakeLists.txt | 114 ++++++++++++++++++++++ fdNRTBase/fdNRTBase.cpp | 198 +++++++++++++++++++++++++++++++++++++++ fdNRTBase/tests.scd | 25 +++++ 3 files changed, 337 insertions(+) create mode 100755 fdNRTBase/CMakeLists.txt create mode 100644 fdNRTBase/fdNRTBase.cpp create mode 100644 fdNRTBase/tests.scd diff --git a/fdNRTBase/CMakeLists.txt b/fdNRTBase/CMakeLists.txt new file mode 100755 index 0000000..be9c700 --- /dev/null +++ b/fdNRTBase/CMakeLists.txt @@ -0,0 +1,114 @@ +####### added the eingenmf +set(FLUID_DECOMP_DIR ../../fluid_decomposition) + +include_directories( + "${FLUID_DECOMP_DIR}" + "${FLUID_DECOMP_DIR}/include" + "${FLUID_DECOMP_DIR}/3rdparty" +) + +####### original SC Cmake file starts here +set(FILENAME "fdNRTBase.cpp") #specify the .cpp file here +cmake_minimum_required (VERSION 2.8) +get_filename_component(PROJECT ${FILENAME} NAME_WE) #automatically sets project name from the filename +message(STATUS "Project name is ${PROJECT}") +project (${PROJECT}) + +include_directories(${SC_PATH}/include/plugin_interface) +include_directories(${SC_PATH}/include/common) +include_directories(${SC_PATH}/common) + +set(CMAKE_SHARED_MODULE_PREFIX "") +if(APPLE OR WIN32) +set(CMAKE_SHARED_MODULE_SUFFIX ".scx") +endif() + +option(SUPERNOVA "Build plugins for supernova" OFF) +if (SUPERNOVA) + include_directories(${SC_PATH}/external_libraries/nova-tt) + # actually just boost.atomic + include_directories(${SC_PATH}/external_libraries/boost) + include_directories(${SC_PATH}/external_libraries/boost_lockfree) + include_directories(${SC_PATH}/external_libraries/boost-lockfree) +endif() + +option(CPP11 "Build with c++11." ON) + +if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(CMAKE_COMPILER_IS_CLANG 1) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) + add_definitions(-fvisibility=hidden) + + include (CheckCCompilerFlag) + include (CheckCXXCompilerFlag) + + CHECK_C_COMPILER_FLAG(-msse HAS_SSE) + CHECK_CXX_COMPILER_FLAG(-msse HAS_CXX_SSE) + + if (HAS_SSE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse") + endif() + if (HAS_CXX_SSE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse") + endif() + + CHECK_C_COMPILER_FLAG(-msse2 HAS_SSE2) + CHECK_CXX_COMPILER_FLAG(-msse2 HAS_CXX_SSE2) + + if (HAS_SSE2) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse2") + endif() + if (HAS_CXX_SSE2) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2") + endif() + + CHECK_C_COMPILER_FLAG(-mfpmath=sse HAS_FPMATH_SSE) + CHECK_CXX_COMPILER_FLAG(-mfpmath=sse HAS_CXX_FPMATH_SSE) + + if (HAS_FPMATH_SSE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpmath=sse") + endif() + if (HAS_CXX_FPMATH_SSE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse") + endif() + + if(NATIVE) + add_definitions(-march=native) + endif() + + if(CPP11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + if(CMAKE_COMPILER_IS_CLANG) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") + endif() + endif() +endif() +if(MINGW) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mstackrealign") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mstackrealign") +endif() + +####### added the fluid_decomposition +add_library( +${PROJECT} +MODULE +${FILENAME} +"${FLUID_DECOMP_DIR}/3rdparty/HISSTools_FFT/HISSTools_FFT.cpp" +) +if(SUPERNOVA) + add_library(${PROJECT}_supernova MODULE ${FILENAME}) + set_property(TARGET ${PROJECT}_supernova + PROPERTY COMPILE_DEFINITIONS SUPERNOVA) +endif() + +add_custom_command( + TARGET + ${PROJECT} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory "../../release-packaging/${PROJECT}/plugins" + COMMAND ${CMAKE_COMMAND} -E copy $ "../../release-packaging/${PROJECT}/plugins" +) + +target_link_libraries (${PROJECT} "-framework Accelerate") diff --git a/fdNRTBase/fdNRTBase.cpp b/fdNRTBase/fdNRTBase.cpp new file mode 100644 index 0000000..b7aebfc --- /dev/null +++ b/fdNRTBase/fdNRTBase.cpp @@ -0,0 +1,198 @@ +//Can I reallocate buffers on the server? Yes I can. +#include "SC_PlugIn.h" +#include +#include "data/FluidTensor.hpp" + +static InterfaceTable *ft; + +namespace fluid { +namespace sc{ + using ViewType = fluid::FluidTensorView; + + /** + A descendent of SndBuf that will populate itself + from the NRT mirror buffers given a world and a bufnum + **/ + struct NRTBuf: public SndBuf + { + NRTBuf(SndBuf& b):SndBuf(b){} + + NRTBuf(World* world,size_t bufnum): + NRTBuf(*World_GetNRTBuf(world,bufnum)) + {} + }; + + /** + A combination of SndBuf and FluidTensorView, for simple transfer of data + + Given a World* and a buffer number, this will populate its SndBuf stuff + from the NRT mirror buffers, and create a FluidTensorView wrapper of + appropriate dimensions. + + The SndBuf can then be 'transferred' back to the RT buffers once we're done with it, + and SC notified of the update. (In the context of SequencedCommands, in which this is meant + to be used, this would happen at Stage3() on the real-time thread) + + **/ + class SCBufferView: public NRTBuf,ViewType + { + public: + SCBufferView() = delete; + SCBufferView(SCBufferView&) = delete; + SCBufferView operator=(SCBufferView&) = delete; + + SCBufferView(size_t bufnum,World* world): + NRTBuf(world,bufnum), + ViewType({0,{static_cast(frames), + static_cast(channels)}},NRTBuf::data), + mBufnum(bufnum), mWorld(world) + {} + + void assignToRT() + { + SndBuf* rtBuf = World_GetBuf(mWorld,mBufnum); + *rtBuf = static_cast(*this); + mWorld->mSndBufUpdates[mBufnum].writes++; + } + + private: + size_t mBufnum; + World * mWorld; + }; + + class NRTCommandBase{ + + + template + using AsyncFn = bool (T::*)(); + + template + using AsyncCleanup = void (T::*) (); + + template F> + static bool call(World*,void* x) + { + return (static_cast(x)->*F)(); + } + + template F> + static void call(World*, void* x) + { + (static_cast(x)->*F)(); + } + + template Stage2, AsyncFn Stage3, AsyncFn Stage4, AsyncCleanup Cleanup> + void cmd(std::string name) + { + (*ft->fDoAsynchronousCommand)( mWorld, mReplyAddr,name.c_str(),this, + call, call, call,call, + mCompletionMsgSize,mCompletionMsgData); + } + + + + void cm() + { + cmd("Bob"); + } + + + + public: + NRTCommandBase() = delete; + NRTCommandBase(NRTCommandBase&) = delete; + NRTCommandBase& operator=(NRTCommandBase&) = delete; + + + NRTCommandBase(size_t buffers_in, size_t buffers_out, World *inWorld, void* inUserData, struct sc_msg_iter *args, void *replyAddr): + input_buffers(buffers_in,-1), output_buffers(buffers_out,-1), + mWorld(inWorld),mReplyAddr(replyAddr) + { + for(auto&& i: input_buffers) + i = args->geti(); + + for(auto&& o: output_buffers) + o = args->geti(); + + mCompletionMsgSize = args->getbsize(); + mCompletionMsgData = 0; + if(mCompletionMsgSize) + { + //allocate string + mCompletionMsgData = (char*)RTAlloc(mWorld,mCompletionMsgSize); + args->getb(mCompletionMsgData,mCompletionMsgSize); + } + + } + + virtual void process() + { + + } + + private: + + bool do_processing() + { + + return true; + } + bool post_processing() + { + return true; + } + bool dummy_stage() { return true; } + void dummy_cleanup() {} + + std::vector input_buffers; + std::vector output_buffers; + + protected: + World * mWorld; + void* mReplyAddr; + const char* cmdName; + void *cmdData; + size_t mCompletionMsgSize; + char* mCompletionMsgData; + + }; +} //namespace supercollider +}//namespace fluid + + +template +void command(World *inWorld, void* inUserData, struct sc_msg_iter *args, void *replyAddr) +{ + NRT_Plug cmd(inWorld, inUserData, args, replyAddr); + + + +} + + +template +void registerCommand(InterfaceTable* ft, const char* name) +{ + //typedef void (*PlugInCmdFunc)(World *inWorld, void* inUserData, struct sc_msg_iter *args, void *replyAddr); + PlugInCmdFunc cmd = command; + + + + (*ft->fDefinePlugInCmd)(name,cmd,nullptr); +} + + +//PluginLoad(BufferFunTime) { +// +// using fluid::sc::NRTCommandBase; +// +// registerCommand(inTable, "ASyncBufMatch"); +// +//// ft = inTable; +//// //BufGen version: all in the NRT thread +////// DefineBufGen("BufMatch", BufferMatch); +//// //ASync version: swaps between NRT and RT threads +//// DefinePlugInCmd("AsyncBufMatch", ASyncBufferFun_Main, nullptr); +//// +//} + diff --git a/fdNRTBase/tests.scd b/fdNRTBase/tests.scd new file mode 100644 index 0000000..e6f5ab6 --- /dev/null +++ b/fdNRTBase/tests.scd @@ -0,0 +1,25 @@ +s.reboot + +//Quickie test of buffer allocation working +//Read a sound file +a = Buffer.read(s,"/Users/owen/Desktop/denoise_stn/sources/01-mix.wav"); +//Pass buffer to this, along with a rank. It will allocate a new buffer, +//size it appropriately (in our server code) and return the new object +f = FDBufferExperiments.allocMatch(s,a,rank:5); +//Make sure everything is kosher: +a.query +f.query + + +//Try full async version +s.reboot + +//Quickie test of buffer allocation working +//Read a sound file +a = Buffer.read(s,"/Users/owen/Desktop/denoise_stn/sources/01-mix.wav"); +//Pass buffer to this, along with a rank. It will allocate a new buffer, +//size it appropriately (in our server code) and return the new object +f = FDBufferExperiments.allocMatchAsync(s,a,rank:5); +//Make sure everything is kosher: +a.query +f.query \ No newline at end of file