fdNRTBase: Base wrapper class for Async commands

nix
Owen Green 7 years ago
parent 535b36b8a7
commit a39f75e241

@ -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 $<TARGET_FILE:${PROJECT}> "../../release-packaging/${PROJECT}/plugins"
)
target_link_libraries (${PROJECT} "-framework Accelerate")

@ -0,0 +1,198 @@
//Can I reallocate buffers on the server? Yes I can.
#include "SC_PlugIn.h"
#include <vector>
#include "data/FluidTensor.hpp"
static InterfaceTable *ft;
namespace fluid {
namespace sc{
using ViewType = fluid::FluidTensorView<float, 2>;
/**
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<size_t>(frames),
static_cast<size_t>(channels)}},NRTBuf::data),
mBufnum(bufnum), mWorld(world)
{}
void assignToRT()
{
SndBuf* rtBuf = World_GetBuf(mWorld,mBufnum);
*rtBuf = static_cast<SndBuf>(*this);
mWorld->mSndBufUpdates[mBufnum].writes++;
}
private:
size_t mBufnum;
World * mWorld;
};
class NRTCommandBase{
template <typename T>
using AsyncFn = bool (T::*)();
template <typename T>
using AsyncCleanup = void (T::*) ();
template<typename T, AsyncFn<T> F>
static bool call(World*,void* x)
{
return (static_cast<T*>(x)->*F)();
}
template<typename T, AsyncCleanup<T> F>
static void call(World*, void* x)
{
(static_cast<T*>(x)->*F)();
}
template<typename T, AsyncFn<T> Stage2, AsyncFn<T> Stage3, AsyncFn<T> Stage4, AsyncCleanup<T> Cleanup>
void cmd(std::string name)
{
(*ft->fDoAsynchronousCommand)( mWorld, mReplyAddr,name.c_str(),this,
call<T,Stage2>, call<T,Stage3>, call<T,Stage4>,call<T,Cleanup>,
mCompletionMsgSize,mCompletionMsgData);
}
void cm()
{
cmd<NRTCommandBase,&NRTCommandBase::do_processing,&NRTCommandBase::post_processing,&NRTCommandBase::dummy_stage,&NRTCommandBase::dummy_cleanup>("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<long> input_buffers;
std::vector<long> output_buffers;
protected:
World * mWorld;
void* mReplyAddr;
const char* cmdName;
void *cmdData;
size_t mCompletionMsgSize;
char* mCompletionMsgData;
};
} //namespace supercollider
}//namespace fluid
template<typename NRT_Plug>
void command(World *inWorld, void* inUserData, struct sc_msg_iter *args, void *replyAddr)
{
NRT_Plug cmd(inWorld, inUserData, args, replyAddr);
}
template <typename NRT_Plug>
void registerCommand(InterfaceTable* ft, const char* name)
{
//typedef void (*PlugInCmdFunc)(World *inWorld, void* inUserData, struct sc_msg_iter *args, void *replyAddr);
PlugInCmdFunc cmd = command<NRT_Plug>;
(*ft->fDefinePlugInCmd)(name,cmd,nullptr);
}
//PluginLoad(BufferFunTime) {
//
// using fluid::sc::NRTCommandBase;
//
// registerCommand<NRTCommandBase>(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);
////
//}

@ -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
Loading…
Cancel
Save