You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
3.6 KiB
C++
133 lines
3.6 KiB
C++
#pragma once
|
|
|
|
#include <clients/rt/GainClient.hpp>
|
|
#include <data/FluidTensor.hpp>
|
|
#include <data/TensorTypes.hpp>
|
|
|
|
#include <SC_PlugIn.hpp>
|
|
|
|
#include <tuple>
|
|
#include <utility>
|
|
#include <vector>
|
|
namespace fluid {
|
|
namespace client {
|
|
|
|
namespace impl {
|
|
template <typename Client, typename T, size_t N> struct SetterDispatchImpl;
|
|
template <typename Client, typename T, size_t N> struct GetterDispatchImpl;
|
|
} // namespace impl
|
|
|
|
template <typename Client, typename... Ts>
|
|
class FluidSCWrapper : public SCUnit {
|
|
public:
|
|
FluidSCWrapper() {
|
|
mInputConnections.reserve(mClient.audioChannelsIn());
|
|
mOutputConnections.reserve(mClient.audioChannelsOut());
|
|
mAudioInputs.reserve(mClient.audioChannelsIn());
|
|
mAudioOutputs.reserve(mClient.audioChannelsOut());
|
|
|
|
for (int i = 0; i < mClient.audioChannelsIn(); ++i) {
|
|
mInputConnections.emplace_back(isAudioRateIn(i));
|
|
mAudioInputs.emplace_back(nullptr, 0, 0);
|
|
}
|
|
|
|
// const Unit *unit = this;
|
|
//
|
|
for (int i = 0; i < mClient.audioChannelsOut(); ++i) {
|
|
mOutputConnections.emplace_back(true);
|
|
mAudioOutputs.emplace_back(nullptr, 0, 0);
|
|
}
|
|
|
|
set_calc_function<FluidSCWrapper, &FluidSCWrapper::next>();
|
|
|
|
// mCalcFunc = [](Unit *u, int n) {
|
|
// FluidSCWrapper *f = static_cast<FluidSCWrapper *>(u);
|
|
// f->next(n);
|
|
// };
|
|
}
|
|
|
|
void next(int n) {
|
|
|
|
setParams(mInBuf + 1); // forward on inputs N + 1 as params
|
|
|
|
const Unit *unit = this;
|
|
for (int i = 0; i < mClient.audioChannelsIn(); ++i) {
|
|
if (mInputConnections[i])
|
|
mAudioInputs[i].reset(IN(i), 0, fullBufferSize());
|
|
}
|
|
|
|
for (int i = 0; i < mClient.audioChannelsOut(); ++i) {
|
|
if (mOutputConnections[i])
|
|
mAudioOutputs[i].reset(out(i), 0, fullBufferSize());
|
|
}
|
|
|
|
mClient.process(mAudioInputs, mAudioOutputs);
|
|
}
|
|
|
|
void setParams(float **inputs) {
|
|
setParams(inputs, std::index_sequence_for<Ts...>());
|
|
}
|
|
|
|
private:
|
|
template <size_t... Is>
|
|
void setParams(float **inputs, std::index_sequence<Is...>) {
|
|
(void)std::initializer_list<int>{
|
|
(impl::SetterDispatchImpl<Client, Ts, Is>::f(mClient, 1, inputs[Is],
|
|
mInputConnections[Is+1]),
|
|
0)...};
|
|
}
|
|
|
|
std::vector<bool> mInputConnections;
|
|
std::vector<bool> mOutputConnections;
|
|
std::vector<HostVector<float>> mAudioInputs;
|
|
std::vector<HostVector<float>> mAudioOutputs;
|
|
|
|
Client mClient;
|
|
};
|
|
|
|
namespace impl {
|
|
template <typename Client, size_t N>
|
|
struct SetterDispatchImpl<Client, FloatT, N> {
|
|
static void f(Client &x, long ac, float *av, bool isAudio) {
|
|
if (!isAudio)
|
|
x.template setter<N>()(*av);
|
|
}
|
|
};
|
|
|
|
template <typename Client, size_t N>
|
|
struct SetterDispatchImpl<Client, LongT, N> {
|
|
static void f(Client &x, long ac, float *av, bool isAudio) {
|
|
if (!isAudio)
|
|
x.template setter<N>()(*av);
|
|
}
|
|
};
|
|
|
|
template <typename Client, size_t N>
|
|
struct SetterDispatchImpl<Client, BufferT, N> {
|
|
static void f(Client *x, long ac, float *av, bool isAudio) {
|
|
if (!isAudio)
|
|
x->template setter<N>()(*av);
|
|
}
|
|
};
|
|
|
|
template <typename Client, size_t N>
|
|
struct SetterDispatchImpl<Client, EnumT, N> {
|
|
static void f(Client *x, long ac, float *av, bool isAudio) {
|
|
if (!isAudio)
|
|
x->template setter<N>()(*av);
|
|
}
|
|
};
|
|
|
|
} // namespace impl
|
|
|
|
template <typename Client, typename... Ts>
|
|
void makeSCWrapper(InterfaceTable *ft, const char *className,
|
|
const std::tuple<Ts...> ¶ms) {
|
|
registerUnit<FluidSCWrapper<Client, typename Ts::first_type...>>(ft,
|
|
className);
|
|
}
|
|
|
|
} // namespace client
|
|
} // namespace fluid
|
|
|