You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This document will sketch out some ideas on how future users could implement plugins
Problem Statement
Currently interested users who would like to develop plugins are faced with three major
hurdles:
setting up and building to project
the system lacks documentation to understand how it works
implementing a plugin requires a significant amount of C programming skills, as well as
several additional steps like creating the JSON description files etc
This document will address problem 3 because it creates a gap between which domain knowledge
(math, algorithms and sound design) is actually required to create a plugin and all the
technical knowledge required that has nothing to do with the actual problem at hand.
Which Simplifications Already Exist
The current approach already includes some good ideas to simplify this, by auto generating
CV and trigger fields
type reflection to manipulate CV and trigger values
This keeps the following implementation details away from users
wrapping types in atomics and adding the
implementing ability to manipulate CVs/triggers plugins dynamically by using field names
registering plugins in the plugin factory so they can be created dynamically by name
Creating a Plugin With the Current Process
Creating a plugin using the current methodology involves three steps:
define the plugin in a mui-SomePluginClass.jsn
generate ctagSomePluginClass.hpp and ctagSomePluginClass.cpp files
implement ctagSomePluginClass::Process(..) method
The first step is creating a file similar to the following
And finally after implementing the actual ctagSoundProcessorCStripM::Process(...)
method we end up with something like this:
#include<tbd/sounds/ctagSoundProcessorCStripM.hpp>
#include<cmath>
#include"helpers/ctagFastMath.hpp"usingnamespaceCTAG::SP;voidctagSoundProcessorCStripM::Process(const ProcessData &data) {
floatfTreble = treble / 4095.f;
if (cv_treble != -1) {
fTreble = data.cv[cv_treble]; // range 0 ..1 or -1 .. 1
}
CStripM.SetTreble(fTreble);
floatfMid = mid / 4095.f;
if (cv_mid != -1) {
fMid = data.cv[cv_mid]; // range 0 ..1 or -1 .. 1
}
CStripM.SetMid(fMid);
// ... more boilerplate
}
// ... helper methods and generated reflection code
Things to be Improved
One major problem with this approach is, that the implementation always needs to be updated
from the json files and JSON files and the actual implementation can even contradict each
other in terms of the plugins CVs/triggers. This is a real problem since the JSON file
is used to inform the APIs about the available plugin parameters.
There is also a significant amount of boiler plate code that could be deduced from the JSON
file like value range limiting. This has to be done manually in the processing function
the MK_BOOL_PAR, MK_INT_PAR_ and MK_FLT_PAR_ range of macros. Take the
implementation of the Bjorklund plugin for example, which contains screens and screens
of boilerplate like this:
Another challenge is that there is still a significant amount of pure C++ complexity users
should not have to concern themselves with. This can be rather intimidating and creates a
lot of noise that users have to ignore and scroll past, in order to get to what they
would actually like to do.
Suggested Improvements
All suggested improvements shouldn't be forced upon users, but rather allow an alternate
easier way to do things. As a first step We propose the following workflow:
have a single folder say plugins/ that contain simple header files, like MyPlugin.hpp putting the entire plugin implementation in a single file
allow users to declare a simple class only requiring a process(...) method
use plain bool, float and int fields to declare CVs/triggers by using C++
attributes
use attributes to add meta information like descriptions, readable field names, field
ranges etc
do the CV/trigger mapping automatically so the user code does not have to handle it
provide CVs preprocessed, scaled, clamped etc
This could result in a single header file containing the entire plugin, that will still
work with IDE code intelligence and could look something like this
#include<tbd/plugin.hpp>/** * a plugin class * * add name and description and put documentation in this help string * to be extracted and added to the docs webpage*/
[[ tbd_plugin(
name="Bjorklund",
is_stereo,
description="Combining Patterns based on Bjorklund's implementation of Euclidian rhythms and mathematical palindromes"
)]]
structBjorklund {
/** * group attributes * * this also groups these values in the web UI and docs and integrate this help * text into the docs */
[[ tbd_group(name="Global", description="Global (Quantizer relative to Master Tune!)") ]]
structGlobal {
/** * declare a property * * this property documentation will be shown in the docs too */
[[ tbd_trigger(name="Trgger") ]]
bool trigger;
[[ tbd_cv(name="Beat Divider", min=0, max=32) ]]
uint beat_divider;
} global;
// more groups and properties .../** * plugin code: plain dsp and math here*/voidprocess(SampleChunk chunk) {
// all is ready to goif global.trigger:
// maybe have some nice operations on sample data?chunk(0, 1ms) /= 2;
}
}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Plugin Implementation Mechanism
This document will sketch out some ideas on how future users could implement plugins
Problem Statement
Currently interested users who would like to develop plugins are faced with three major
hurdles:
several additional steps like creating the JSON description files etc
This document will address problem 3 because it creates a gap between which domain knowledge
(math, algorithms and sound design) is actually required to create a plugin and all the
technical knowledge required that has nothing to do with the actual problem at hand.
Which Simplifications Already Exist
The current approach already includes some good ideas to simplify this, by auto generating
This keeps the following implementation details away from users
Creating a Plugin With the Current Process
Creating a plugin using the current methodology involves three steps:
mui-SomePluginClass.jsn
ctagSomePluginClass.hpp
andctagSomePluginClass.cpp
filesctagSomePluginClass::Process(..)
methodThe first step is creating a file similar to the following
This automatically creates a header like this
And finally after implementing the actual
ctagSoundProcessorCStripM::Process(...)
method we end up with something like this:
Things to be Improved
One major problem with this approach is, that the implementation always needs to be updated
from the json files and JSON files and the actual implementation can even contradict each
other in terms of the plugins CVs/triggers. This is a real problem since the JSON file
is used to inform the APIs about the available plugin parameters.
There is also a significant amount of boiler plate code that could be deduced from the JSON
file like value range limiting. This has to be done manually in the processing function
the
MK_BOOL_PAR
,MK_INT_PAR_
andMK_FLT_PAR_
range of macros. Take theimplementation of the Bjorklund plugin for example, which contains screens and screens
of boilerplate like this:
Another challenge is that there is still a significant amount of pure C++ complexity users
should not have to concern themselves with. This can be rather intimidating and creates a
lot of noise that users have to ignore and scroll past, in order to get to what they
would actually like to do.
Suggested Improvements
All suggested improvements shouldn't be forced upon users, but rather allow an alternate
easier way to do things. As a first step We propose the following workflow:
plugins/
that contain simple header files, likeMyPlugin.hpp
putting the entire plugin implementation in a single fileprocess(...)
methodbool
,float
andint
fields to declare CVs/triggers by using C++attributes
ranges etc
This could result in a single header file containing the entire plugin, that will still
work with IDE code intelligence and could look something like this
Beta Was this translation helpful? Give feedback.
All reactions