template<class Derived, class Ext1 = end, class Ext2 = end, class Ext3 = end, class Ext4 = end, class Ext5 = end, class Ext6 = end, class Ext7 = end, class Ext8 = end, class Ext9 = end>
class lvtk::Plugin< Derived, Ext1, Ext2, Ext3, Ext4, Ext5, Ext6, Ext7, Ext8, Ext9 >
This is a template base class for LV2 plugins. It has default
implementations for all functions, so you only have to implement the
functions that you need (for example run()). All subclasses must have
a constructor whose signature matches the one in the example code below,
otherwise it will not work with the register_class() function. The
host will use this @c double parameter to pass the sample rate that the
plugin should run at when it creates a new instance of the plugin.
This is a template so that simulated dynamic binding can be used for
the callbacks. This is not all that useful for simple plugins but it may
come in handy when using @ref pluginmixins "mixins" and it doesn't add
any additional vtable lookup and function call costs, like real dynamic
binding would.
#include <cstring>
#include <lvtk/plugin.hpp>
class TestLV2 :
public Plugin<TestLV2>
{
public:
TestLV2(double) : plugin<TestLV2>(2) { }
void run(uint32_t sample_count)
{
std::memcpy(
p(1),
p(0), sample_count *
sizeof(
float));
}
};
If the above code is compiled and linked with @c -ldaps-plugin0 into a
shared module, it could form the shared object part of a fully
functional (but not very useful) LV2 plugin with one audio input port
and one audio output port that just copies the input to the output.
You can extend your plugin classes, for example adding support for
LV2 extensions, by passing @ref pluginmixins "mixin classes" as template
parameters to plugin (second template parameter and onwards).
If you want to write a synth plugin you should probably inherit the
Synth class instead of this one. - Examples:
- silence.cpp, and workhorse.cpp.
Use this function to access and cast port buffers, for example
like this:
@code
LV2_Atom_Sequence* midi = p<LV2_Atom_Sequence>(midi_port);
If you want to access a port buffer as a pointer-to-float (i.e. an audio or control port) you can use the non-template version instead.
- Parameters
-
| port | The index of the port whose buffer you want to access. |
Reimplemented in Synth< V, D, Ext1, Ext2, Ext3, Ext4, Ext5, Ext6, Ext7 >, and Synth< V, D, Ext1, Ext2, Ext3, Ext4, Ext5, Ext6, Ext7 >.
| float*& p |
( |
uint32_t |
port | ) |
|
|
inlineprotected |
Use this function to access data buffers for control or audio ports.
- Parameters
-
| port | The index of the port whose buffer you want to access. |
Reimplemented in Synth< V, D, Ext1, Ext2, Ext3, Ext4, Ext5, Ext6, Ext7 >, and Synth< V, D, Ext1, Ext2, Ext3, Ext4, Ext5, Ext6, Ext7 >.
| static unsigned register_class |
( |
const char * |
uri | ) |
|
|
inlinestatic |
Use this function to register your plugin class so that the host
can find it. You need to do this when the shared library is loaded
by the host. One portable way of doing that is to put the function
call in the initialiser for a global variable, like this:
@code
unsigned _ = MypluginClass::register_class("http://my.plugin.class");
The return value is not important, it's just there so you can use that
trick.
| void run |
( |
uint32_t |
sample_count | ) |
|
|
inline |
This is the process callback which should fill all output port buffers. You most likely want to override it - the default implementation does nothing.
Remember that if you want your plugin to be realtime safe, this function may not block, allocate memory or take more than O(sample_count) time to execute.
- Parameters
-
| sample_count | The number of audio frames to process/generate in this call. |
Reimplemented in Synth< V, D, Ext1, Ext2, Ext3, Ext4, Ext5, Ext6, Ext7 >.