Merge branch 'ParametersWithTuples' of https://bitbucket.org/flucoma/flucoma-supercollider into ParametersWithTuples

nix
Gerard 7 years ago
commit 7137871eed

@ -19,6 +19,7 @@ namespace client {
template <typename Client> class FluidSCWrapper; template <typename Client> class FluidSCWrapper;
namespace impl { namespace impl {
template <typename Client, typename T, size_t N> struct Setter; template <typename Client, typename T, size_t N> struct Setter;
template <size_t N, typename T> struct ArgumentGetter; template <size_t N, typename T> struct ArgumentGetter;
template <size_t N, typename T> struct ControlGetter; template <size_t N, typename T> struct ControlGetter;
@ -33,11 +34,33 @@ template <size_t N, typename T, msg_iter_method<T> Method> struct GetArgument
} }
}; };
template <size_t N, typename T> struct GetControl
struct FloatControlsIter
{ {
T operator()(World*, float **controls) { return *controls[N]; } FloatControlsIter(float** vals, size_t N):mValues(vals), mSize(N) {}
float next()
{
assert(mCount + 1 < mSize);
return *mValues[mCount++];
}
void reset(float** vals)
{
mValues = vals;
mCount = 0;
}
private:
float** mValues;
size_t mSize;
size_t mCount{0};
}; };
template <size_t N, typename T> struct GetControl
{
T operator()(World*, FloatControlsIter& controls) { return controls.next(); }
};
template <size_t N> struct ArgumentGetter<N, FloatT> : public GetArgument<N, float, &sc_msg_iter::getf> template <size_t N> struct ArgumentGetter<N, FloatT> : public GetArgument<N, float, &sc_msg_iter::getf>
{}; {};
@ -59,9 +82,38 @@ template <size_t N> struct ArgumentGetter<N, BufferT>
} }
}; };
template <size_t N> struct ArgumentGetter<N, FloatPairsArrayT>
{
typename FloatPairsArrayT::type operator()(World* w, sc_msg_iter *args)
{
return {{args->getf(),args->getf()},{args->getf(),args->getf()}};
}
};
template <size_t N, typename T> struct ControlGetter : public GetControl<N, typename T::type> template <size_t N, typename T> struct ControlGetter : public GetControl<N, typename T::type>
{}; {};
template <size_t N> struct ControlGetter<N, BufferT>
{
auto operator()(World* w, FloatControlsIter& iter)
{
long bufnum = iter.next();
return std::unique_ptr<BufferAdaptor>(new SCBufferAdaptor(bufnum,w));
}
};
template<size_t N>
struct ControlGetter<N,FloatPairsArrayT>
{
typename FloatPairsArrayT::type operator()(World*, FloatControlsIter& iter)
{
return {{iter.next(),iter.next()},{iter.next(),iter.next()}};
}
};
//template <size_t N, typename //template <size_t N, typename
template <class Wrapper> class RealTime : public SCUnit template <class Wrapper> class RealTime : public SCUnit
@ -72,7 +124,7 @@ template <class Wrapper> class RealTime : public SCUnit
public: public:
static void setup(InterfaceTable *ft, const char *name) { registerUnit<Wrapper>(ft, name); } static void setup(InterfaceTable *ft, const char *name) { registerUnit<Wrapper>(ft, name); }
RealTime() {} RealTime():mControlsIterator{nullptr,0} {}
void init() void init()
{ {
@ -105,7 +157,8 @@ public:
{ {
Wrapper *w = static_cast<Wrapper *>(this); Wrapper *w = static_cast<Wrapper *>(this);
auto &client = w->client(); auto &client = w->client();
w->setParams( mWorld->mVerbosity > 0, mWorld,mInBuf + client.audioChannelsIn()); // forward on inputs N + audio inputs as params mControlsIterator.reset(mInBuf + client.audioChannelsIn());
w->setParams( mWorld->mVerbosity > 0, mWorld,mControlsIterator); // forward on inputs N + audio inputs as params
const Unit *unit = this; const Unit *unit = this;
for (int i = 0; i < client.audioChannelsIn(); ++i) for (int i = 0; i < client.audioChannelsIn(); ++i)
{ {
@ -123,6 +176,7 @@ private:
std::vector<bool> mOutputConnections; std::vector<bool> mOutputConnections;
std::vector<HostVector> mAudioInputs; std::vector<HostVector> mAudioInputs;
std::vector<HostVector> mAudioOutputs; std::vector<HostVector> mAudioOutputs;
FloatControlsIter mControlsIterator;
}; };
template <class Wrapper> class NonRealTime template <class Wrapper> class NonRealTime
@ -292,7 +346,7 @@ public:
impl::FluidSCWrapperBase<Client>::setup(ft, name); impl::FluidSCWrapperBase<Client>::setup(ft, name);
} }
auto setParams(bool verbose, World* world, float **inputs) auto setParams(bool verbose, World* world, impl::FloatControlsIter& inputs)
{ {
return mClient.template setParameterValues<impl::ControlGetter>(verbose, world, inputs); return mClient.template setParameterValues<impl::ControlGetter>(verbose, world, inputs);
} }

@ -1,101 +1,14 @@
// FD_BufHPSS, an NRT buffer HPSS Processor // FD_BufHPSS, an NRT buffer HPSS Processor
// A tool from the FluCoMa project, funded by the European Research Council (ERC) under the European Unions Horizon 2020 research and innovation programme (grant agreement No 725899) // A tool from the FluCoMa project, funded by the European Research Council (ERC) under the European Unions Horizon 2020 research and innovation programme (grant agreement No 725899)
#include "fdNRTBase.hpp" #include <clients/rt/HPSSClient.hpp>
#include "algorithms/STFT.hpp" #include <clients/nrt/FluidNRTClientWrapper.hpp>
#include "data/FluidTensor.hpp" #include <FluidSCWrapper.hpp>
#include "clients/nrt/HPSS.hpp"
#include "clients/common/FluidParams.hpp"
#include "SC_PlugIn.h"
#include <unordered_set>
#include <vector>
static InterfaceTable *ft; static InterfaceTable *ft;
//Using statements for fluidtensor
using fluid::FluidTensor;
using fluid::FluidTensorView;
namespace fluid {
namespace wrapper{
class BufHPSS: public NRTCommandBase
{
/*
- srcbuf num
 src start frame
- src numframes
src start chan
 src num chans
 harms dst
 perc dst
 window size
 hop size
 fft size
*/
public:
using client_type = client::HPSSClient;
using NRTCommandBase::NRTCommandBase;
~BufHPSS() {}
void runCommand(World* world, void* replyAddr, char* completionMsgData, size_t completionMsgSize)
{
cmd<BufHPSS, &BufHPSS::process, &BufHPSS::postProcess, &BufHPSS::postComplete>(world, "/BufHPSS", replyAddr, completionMsgData, completionMsgSize);
}
bool process(World* world)
{
//sanity check the parameters
bool parametersOk;
client::HPSSClient::ProcessModel processModel;
std::string whatHappened;//this will give us a message to pass back if param check fails
std::tie(parametersOk,whatHappened,processModel) = processor.sanityCheck();
if(!parametersOk)
{
Print("fdHPSS: %s \n", whatHappened.c_str());
return false;
}
//Now, we can proceed
processor.process(processModel);
mModel = processModel;
return true;
}
bool postProcess(World* world)
{
static_cast<SCBufferView*>(mModel.harm)->assignToRT(world);
static_cast<SCBufferView*>(mModel.perc)->assignToRT(world);
if(mModel.res)
static_cast<SCBufferView*>(mModel.res)->assignToRT(world);
return true;
}
bool postComplete(World*) {
static_cast<SCBufferView*>(mModel.harm)->cleanUp();
static_cast<SCBufferView*>(mModel.perc)->cleanUp();
if(mModel.res)
static_cast<SCBufferView*>(mModel.res)->cleanUp();
return true;
}
std::vector<client::Instance>& parameters()
{
return processor.getParams();
}
private:
client::HPSSClient processor;
client::HPSSClient::ProcessModel mModel;
};//class
} //namespace wrapper
}//namespace fluid
PluginLoad(OfflineFluidDecompositionUGens) { PluginLoad(OfflineFluidDecompositionUGens) {
ft = inTable; ft = inTable;
registerCommand<fluid::wrapper::BufHPSS,fluid::client::HPSSClient>(ft, "BufHPSS"); using namespace fluid::client;
fluid::wrapper::printCmd<fluid::client::HPSSClient>(ft,"BufHPSS","FDHPSS"); makeSCWrapper<NRTStreamAdaptor<HPSSClient<double,float>>>(ft, "BufHPSS");
} }

@ -2,74 +2,13 @@
// A tool from the FluCoMa project, funded by the European Research Council (ERC) under the European Unions Horizon 2020 research and innovation programme (grant agreement No 725899) // A tool from the FluCoMa project, funded by the European Research Council (ERC) under the European Unions Horizon 2020 research and innovation programme (grant agreement No 725899)
#include "clients/nrt/NoveltyClient.hpp" #include <clients/nrt/NoveltyClient.hpp>
#include "fdNRTBase.hpp" #include <FluidSCWrapper.hpp>
#include "data/FluidTensor.hpp"
#include "clients/common/FluidParams.hpp"
//#include "SC_PlugIn.h"
//#include <unordered_set>
//#include <vector>
static InterfaceTable *ft;
namespace fluid {
namespace wrapper{
class BufNoveltySlice: public NRTCommandBase
{
public:
using client_type = client::NoveltyClient;
using NRTCommandBase::NRTCommandBase;
~BufNoveltySlice() {}
void runCommand(World* world, void* replyAddr, char* completionMsgData, size_t completionMsgSize)
{
cmd<BufNoveltySlice, &BufNoveltySlice::process, &BufNoveltySlice::postProcess, &BufNoveltySlice::postComplete>(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<SCBufferView*>(mModel.indices)->assignToRT(world);
return true;
}
bool postComplete(World*) {
static_cast<SCBufferView*>(mModel.indices)->cleanUp();
return true;
}
std::vector<client::Instance>& parameters()
{
return trans.getParams();
}
private:
client_type trans;
client_type::ProcessModel mModel;
};//class
} //namespace wrapper
}//namespace fluid
static InterfaceTable* ft;
PluginLoad(OfflineFluidDecompositionUGens) { PluginLoad(OfflineFluidDecompositionUGens) {
ft = inTable; ft = inTable;
registerCommand<fluid::wrapper::BufNoveltySlice,fluid::client::NoveltyClient>(ft, "BufNoveltySlice"); using namespace fluid::client;
fluid::wrapper::printCmd<fluid::client::NoveltyClient>(ft,"BufNoveltySlice","FluidBufNoveltySlice"); makeSCWrapper<NoveltyClient>(ft, "BufNoveltySlice");
} }

@ -1,140 +1,14 @@
// A tool from the FluCoMa project, funded by the European Research Council (ERC) under the European Unions Horizon 2020 research and innovation programme (grant agreement No 725899) // A tool from the FluCoMa project, funded by the European Research Council (ERC) under the European Unions Horizon 2020 research and innovation programme (grant agreement No 725899)
#include <clients/rt/HPSSClient.hpp>
#include "SC_PlugIn.hpp" #include <FluidSCWrapper.hpp>
#include "data/FluidTensor.hpp"
#include "clients/rt/HPSSClient.hpp"
static InterfaceTable *ft; static InterfaceTable *ft;
namespace fluid {
namespace wrapper{
class FDRTHPSS: public SCUnit
{
using AudioSignalWrapper = client::HPSSClient<double, float>::AudioSignal;
using SignalWrapper = client::HPSSClient<double, float>::Signal<float>;
using SignalPointer = std::unique_ptr<SignalWrapper>;
using ClientPointer = std::unique_ptr<client::HPSSClient<double,float>>;
template <size_t N>
using SignalArray = std::array<SignalPointer,N>;
public:
FDRTHPSS()
{
//Order of args
//psize hszie pthresh hthresh Window size, Hop size, FFT Size
//Oh NO! Heap allocation! Make client object
mClient = ClientPointer(new client::HPSSClient<double,float>(65536));
setParams(true);
bool isOK;
std::string feedback;
std::tie(isOK, feedback) = mClient->sanityCheck();
if(!isOK)
{
Print("fdRTHPSS Error: %s",feedback.c_str());
return;
}
mClient->setHostBufferSize(bufferSize());
mClient->reset();
//Work out what signals we need. For now keep it simple:
inputSignals[0] = SignalPointer(new AudioSignalWrapper());
outputSignals[0] = SignalPointer(new AudioSignalWrapper());
outputSignals[1] = SignalPointer(new AudioSignalWrapper());
outputSignals[2] = SignalPointer(new AudioSignalWrapper());
mCalcFunc = make_calc_function<FDRTHPSS,&FDRTHPSS::next>();
Unit* unit = this;
ClearUnitOutputs(unit,1);
}
~FDRTHPSS() {}
private:
void setParams(bool instantiation)
{
assert(mClient);
for(size_t i = 0; i < mClient->getParams().size(); ++i)
{
client::Instance& p = mClient->getParams()[i];
if(!instantiation && p.getDescriptor().instantiation())
continue;
switch(p.getDescriptor().getType())
{
case client::Type::kLong:
p.setLong(in0(i + 1));
p.checkRange();
break;
case client::Type::kFloat: {
// We need to constrain threshold (normalised) frequency pairs at
// runtime.
std::string attrname = p.getDescriptor().getName();
auto constraint = paramConstraints.find(attrname);
if (constraint != paramConstraints.end()) {
double limit = client::lookupParam(constraint->second.param,
mClient->getParams())
.getFloat();
if (!constraint->second.condition(in0(i + 1), limit)) {
return;
}
}
p.setFloat(in0(i + 1));
p.checkRange();
}
break;
case client::Type::kBuffer:
// p.setBuffer( in0(i+1));
break;
default:
break;
}
}
}
void next(int numsamples)
{
setParams(false);
const float* input = in(0);
const float inscalar = in0(0);
inputSignals[0]->set(const_cast<float*>(input), inscalar);
outputSignals[0]->set(out(0), out0(0));
outputSignals[1]->set(out(1), out0(1));
outputSignals[2]->set(out(2), out0(2));
mClient->doProcess(std::begin(inputSignals),std::end(inputSignals),std::begin(outputSignals), std::end(outputSignals),numsamples,1,3);
}
struct Constraint{
std::string param;
std::function<bool(double, double)> condition;
};
std::map<std::string, Constraint> paramConstraints{
{"ptf1",{"ptf2", std::less<double>()}},
{"htf1",{"htf2", std::less<double>()}},
{"ptf2",{"ptf1", std::greater<double>()}},
{"htf2",{"htf1", std::greater<double>()}}
};
ClientPointer mClient;
SignalArray<1> inputSignals;
SignalArray<3> outputSignals;
};
}
}
PluginLoad(FluidSTFTUGen) { PluginLoad(FluidSTFTUGen) {
ft = inTable; ft = inTable;
registerUnit<fluid::wrapper::FDRTHPSS>(ft, "FluidHPSS"); using namespace fluid::client;
makeSCWrapper<HPSSClient<double,float>>(ft, "FluidHPSS");
} }

Loading…
Cancel
Save