fdNRTBase: Base wrapper class for Async commands
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…
Reference in New Issue