rt-vamp-plugin-sdk 0.3.1
Real-time Vamp plugin SDK for C++20
Loading...
Searching...
No Matches
Plugin.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <complex>
5#include <concepts>
6#include <cstdint>
7#include <optional>
8#include <span>
9#include <string>
10#include <string_view>
11#include <variant>
12#include <vector>
13
14// Vamp C API uses unsigned int as size type (blockSize, stepSize, channelCount, outputCount, ...).
15// Make sure it has at least 32 bit and use uint32_t as size type in C++ interfaces.
16static_assert(sizeof(unsigned int) >= sizeof(uint32_t), "Size type must have at least 32 bit");
17
18namespace rtvamp::pluginsdk {
19
24public:
25 PluginBase() = default;
26 virtual ~PluginBase() = default;
27
28 PluginBase(const PluginBase&) = default;
29 PluginBase(PluginBase&&) = default;
30 PluginBase& operator=(const PluginBase&) = default;
32
34 enum class InputDomain { Time, Frequency };
35
37 // use const char* for compile-time evaluation and mapping to C API
38 const char* identifier = "";
39 const char* name = "";
40 const char* description = "";
41 const char* unit = "";
42 float defaultValue = 0.0F;
43 float minValue = 0.0F;
44 float maxValue = 0.0F;
45 std::optional<float> quantizeStep = std::nullopt;
46 // std::vector<const char*> valueNames{}; // currently not possible -> wait for constexpr vectors
47 };
48
50 std::string identifier;
51 std::string name;
52 std::string description;
53 std::string unit;
54 uint32_t binCount = 1;
55 std::vector<std::string> binNames = {}; // NOLINT(*redundant-member-init)
56 bool hasKnownExtents = false;
57 float minValue = 0.0F;
58 float maxValue = 0.0F;
59 std::optional<float> quantizeStep = std::nullopt;
60 };
61
62 using TimeDomainBuffer = std::span<const float>;
63 using FrequencyDomainBuffer = std::span<const std::complex<float>>;
64 using InputBuffer = std::variant<TimeDomainBuffer, FrequencyDomainBuffer>;
65 using Feature = std::vector<float>;
66};
67
79template <uint32_t NOutputs>
80class Plugin : public PluginBase {
81public:
82 explicit constexpr Plugin(float inputSampleRate) : inputSampleRate_(inputSampleRate) {}
83
84 using OutputList = std::array<OutputDescriptor, NOutputs>;
85 using FeatureSet = std::array<Feature, NOutputs>;
86
87 static constexpr uint32_t outputCount = NOutputs;
88
90 struct Meta {
91 const char* identifier = "";
92 const char* name = "";
93 const char* description = "";
94 const char* maker = "";
95 const char* copyright = "";
98 };
99
100 static constexpr Meta meta{};
101 static constexpr std::array<ParameterDescriptor, 0> parameters{};
102 static constexpr std::array<const char*, 0> programs{};
103
104 virtual std::optional<float> getParameter(std::string_view id) const { return {}; }
105 virtual bool setParameter(std::string_view id, float value) { return false; }
106
107 virtual std::string_view getCurrentProgram() const { return {}; }
108 virtual bool selectProgram(std::string_view name) { return false; }
109
110 virtual uint32_t getPreferredStepSize() const { return 0; }
111 virtual uint32_t getPreferredBlockSize() const { return 0; }
112
113 virtual OutputList getOutputDescriptors() const = 0;
114
115 virtual bool initialise(uint32_t stepSize, uint32_t blockSize) = 0;
116 virtual void reset() = 0;
117 virtual const FeatureSet& process(InputBuffer buffer, uint64_t nsec) = 0;
118
119protected:
120 float getInputSampleRate() const noexcept { return inputSampleRate_; };
121 FeatureSet& getFeatureSet() noexcept { return featureSet_; }
122
124 const auto outputs = getOutputDescriptors();
125 auto& featureSet = getFeatureSet();
126 for (size_t i = 0; i < outputCount; ++i) {
127 featureSet[i].resize(outputs[i].binCount);
128 }
129 }
130
131private:
132 float inputSampleRate_;
133 FeatureSet featureSet_;
134};
135
136/* ------------------------------------------- Concept ------------------------------------------ */
137
138template <typename T>
139concept HasParameters = requires {
140 { T::parameters } -> std::convertible_to<std::array<PluginBase::ParameterDescriptor, T::parameters.size()>>;
141};
142
143template <typename T>
144concept HasPrograms = requires {
145 { T::programs } -> std::convertible_to<std::array<const char*, T::programs.size()>>;
146};
147
148template <typename T>
149concept IsPlugin = std::constructible_from<T, float> && requires(
150 T plugin,
151 std::string_view parameterName,
152 float parameterValue,
153 std::string_view programName,
154 uint32_t stepSize,
155 uint32_t blockSize,
157 uint64_t nsec
158) {
159 { T::outputCount } -> std::convertible_to<uint32_t>;
160 { T::meta } -> std::convertible_to<typename T::Meta>;
161
162 requires (!HasParameters<T> || requires {
163 { plugin.getParameter(parameterName) } -> std::same_as<std::optional<float>>;
164 { plugin.setParameter(parameterName, parameterValue) } -> std::same_as<bool>;
165 });
166
167 requires (!HasPrograms<T> || requires {
168 { plugin.getCurrentProgram() } -> std::same_as<std::string_view>;
169 { plugin.selectProgram(programName) } -> std::same_as<bool>;
170 });
171
172 { plugin.getPreferredStepSize() } -> std::same_as<uint32_t>;
173 { plugin.getPreferredBlockSize() } -> std::same_as<uint32_t>;
174 { plugin.getOutputDescriptors() } -> std::same_as<std::array<PluginBase::OutputDescriptor, T::outputCount>>;
175 { plugin.initialise(stepSize, blockSize) } -> std::same_as<bool>;
176 { plugin.reset() } -> std::same_as<void>;
177 { plugin.process(buffer, nsec) } -> std::convertible_to<const std::array<PluginBase::Feature, T::outputCount>&>;
178};
179
180} // namespace rtvamp::pluginsdk
Non-templated plugin base class with type definitions.
Definition Plugin.hpp:23
PluginBase & operator=(PluginBase &&)=default
std::span< const std::complex< float > > FrequencyDomainBuffer
Frequency domain buffer (FFT)
Definition Plugin.hpp:63
virtual ~PluginBase()=default
std::span< const float > TimeDomainBuffer
Time domain buffer.
Definition Plugin.hpp:62
InputDomain
Input domain of the plugin.
Definition Plugin.hpp:34
std::variant< TimeDomainBuffer, FrequencyDomainBuffer > InputBuffer
Input domain variant.
Definition Plugin.hpp:64
PluginBase(PluginBase &&)=default
std::vector< float > Feature
Feature with one or more values (defined by OutputDescriptor::binCount)
Definition Plugin.hpp:65
PluginBase(const PluginBase &)=default
PluginBase & operator=(const PluginBase &)=default
Base class to implement feature extraction plugins.
Definition Plugin.hpp:80
static constexpr Meta meta
Required static plugin descriptor.
Definition Plugin.hpp:100
static constexpr uint32_t outputCount
Number of outputs (defined by template parameter)
Definition Plugin.hpp:87
virtual uint32_t getPreferredStepSize() const
Definition Plugin.hpp:110
FeatureSet & getFeatureSet() noexcept
Definition Plugin.hpp:121
virtual void reset()=0
virtual bool selectProgram(std::string_view name)
Definition Plugin.hpp:108
virtual bool setParameter(std::string_view id, float value)
Definition Plugin.hpp:105
float getInputSampleRate() const noexcept
Definition Plugin.hpp:120
void initialiseFeatureSet()
Definition Plugin.hpp:123
std::array< OutputDescriptor, NOutputs > OutputList
List of output descriptors.
Definition Plugin.hpp:84
virtual std::string_view getCurrentProgram() const
Definition Plugin.hpp:107
virtual const FeatureSet & process(InputBuffer buffer, uint64_t nsec)=0
virtual bool initialise(uint32_t stepSize, uint32_t blockSize)=0
std::array< Feature, NOutputs > FeatureSet
Computed features for each output.
Definition Plugin.hpp:85
constexpr Plugin(float inputSampleRate)
Definition Plugin.hpp:82
virtual uint32_t getPreferredBlockSize() const
Definition Plugin.hpp:111
static constexpr std::array< ParameterDescriptor, 0 > parameters
Optional parameter descriptors (default: none)
Definition Plugin.hpp:101
static constexpr std::array< const char *, 0 > programs
Optional program list (default: none)
Definition Plugin.hpp:102
virtual std::optional< float > getParameter(std::string_view id) const
Definition Plugin.hpp:104
virtual OutputList getOutputDescriptors() const =0
Definition Plugin.hpp:139
Definition Plugin.hpp:144
Definition Plugin.hpp:149
Definition EntryPoint.hpp:8
std::string identifier
Definition Plugin.hpp:50
std::string name
Definition Plugin.hpp:51
float maxValue
Definition Plugin.hpp:58
std::string description
Definition Plugin.hpp:52
bool hasKnownExtents
Definition Plugin.hpp:56
float minValue
Definition Plugin.hpp:57
std::vector< std::string > binNames
Definition Plugin.hpp:55
uint32_t binCount
Definition Plugin.hpp:54
std::string unit
Definition Plugin.hpp:53
std::optional< float > quantizeStep
Definition Plugin.hpp:59
std::optional< float > quantizeStep
Definition Plugin.hpp:45
const char * description
Definition Plugin.hpp:40
const char * name
Definition Plugin.hpp:39
const char * identifier
Definition Plugin.hpp:38
const char * unit
Definition Plugin.hpp:41
Static plugin descriptor.
Definition Plugin.hpp:90
int pluginVersion
Definition Plugin.hpp:96
const char * copyright
Definition Plugin.hpp:95
const char * identifier
Definition Plugin.hpp:91
InputDomain inputDomain
Definition Plugin.hpp:97
const char * name
Definition Plugin.hpp:92
const char * maker
Definition Plugin.hpp:94
const char * description
Definition Plugin.hpp:93