|
Operator SDK
Build MIDI processing and UI modes for the Operator device
|
Declarative parameter-table DSL for Operator SDK modes. More...
#include <operator_sdk.h>#include <algorithm>#include <array>#include <cstddef>#include <cstdint>#include <initializer_list>#include <string_view>#include <tuple>#include <type_traits>#include <utility>#include <config_generated.h>Classes | |
| struct | op::params::Numeric |
| An integer parameter with a min, max, step, and optional decimals. More... | |
| struct | op::params::Bool |
| A two-state on/off toggle. More... | |
| struct | op::params::Enum |
| A single choice from a fixed list of named options. More... | |
| struct | op::params::List |
| A multi-select set of named options stored as a bitmask. More... | |
| struct | op::params::Note |
| A single MIDI note (0..127) shown with a note-name label. More... | |
| struct | op::params::Range |
| A low/high pair of integers (a span the user dials at both ends). More... | |
| struct | op::params::NoteRange |
| A low/high pair of MIDI notes shown with note-name labels. More... | |
| struct | op::params::FilePicker |
| A picker that lets the user choose a file from storage. More... | |
| struct | op::params::FilePickerValue< Spec > |
| The value returned by param<>() for a FilePicker parameter. More... | |
| struct | op::params::Section |
| A named grouping header for the params that follow it. More... | |
| struct | op::params::Action |
| A button that runs one of the mode's functions when selected. More... | |
Namespaces | |
| namespace | op::params |
| Declarative parameter DSL for modes: param specs and widget builders. | |
| namespace | op |
| Root namespace for the Operator SDK. | |
Macros | |
| #define | OP_MODE_PARAMS(...) |
| Declare a mode's full parameter table in one call. | |
| #define | OP_MODE_NO_PARAMS() |
| Declare that a mode exposes no user-facing parameters. | |
| #define | OP_MODE_REGISTER(...) |
| Export a mode's core lifecycle hooks to the firmware. | |
| #define | OP_MODE_REGISTER_UI(render_fn, gesture_fn) |
| Export a custom-UI mode's render and gesture hooks. | |
Typedefs | |
| using | op::params::Op = ::op::modes::op_params::Op |
| Comparison used by a parameter's visible_when gate. | |
Functions | |
| template<typename T> | |
| constexpr VisibleWhen | op::params::gate (const T &watcher, Op op, int8_t value) |
| Gate a parameter's visibility on another parameter's current value. | |
| constexpr VisibleWhen | op::params::hidden () |
| Mark a state-only param as always hidden. | |
| template<typename... Children> | |
| constexpr detail::SectionGroup< Children... > | op::params::make_section (std::string_view name, Children... children) |
| Build a Section together with its children in one expression. | |
Declarative parameter-table DSL for Operator SDK modes.
Describe each parameter as a small, kind-specific struct and pass them all to OP_MODE_PARAMS(). The SDK builds the string table and emits the three ABI globals the firmware reads (kParams, kParamCount, kParamStrings) for you, so you fill in only the fields that matter for each parameter.
Usage:
#include <operator_sdk.h>
#include <operator_sdk/params.h>
OP_MODE_PARAMS(
op::params::Numeric{.name = "Transpose", .min = -12, .max = 12,
.default_ = 0},
op::params::Bool {.name = "Enable", .default_ = true},
op::params::Enum {.name = "Channel",
.options = {"All","Ch 1","Ch 2","Ch 3",
"Ch 4","Ch 5","Ch 6","Ch 7",
"Ch 8","Ch 9","Ch 10","Ch 11",
"Ch 12","Ch 13","Ch 14","Ch 15",
"Ch 16"},
.default_ = 0}
);
Parameter kinds, each a struct in this namespace:
Every kind carries .name, an optional .parent Section, an optional .visible_when gate, and .is_per_instance. The kind-specific fields (.min, .options, .default_, and so on) are documented on each struct below. Read a value at run time with param<Obj>(), which returns the int32 value, a std::pair for the Range kinds, or a FilePickerValue for FilePicker.
This header is opt-in. operator_sdk.h does not transitively include it.
| #define OP_MODE_NO_PARAMS | ( | ) |
Declare that a mode exposes no user-facing parameters.
Use this instead of OP_MODE_PARAMS for a custom-UI mode that keeps all of its state internally. It emits the ABI globals the firmware requires and makes op::api available. Call it exactly once per mode.
| #define OP_MODE_PARAMS | ( | ... | ) |
Declare a mode's full parameter table in one call.
Pass every parameter descriptor (Numeric, Bool, Enum, and so on, or a make_section() group) and the SDK stages them, computes the string table, and emits the three ABI globals the firmware reads (kParams, kParamCount, kParamStrings). To be called exactly once per mode. It also makes the param<>() accessor available for reading each parameter's value back.
OP_MODE_PARAMS(Bpm, Bypass, make_section("LFO", On, Rate));
Use OP_MODE_NO_PARAMS() instead for a mode with no declarative params.
| #define OP_MODE_REGISTER | ( | ... | ) |
Export a mode's core lifecycle hooks to the firmware.
It takes the init, process, and destroy functions and wraps them as the extern "C" mode_init, mode_process, and mode_destroy symbols the device loads, assigning op::api before init runs. The three take these shapes:
void init(); void process(OpMidiMessage* msgs, uint8_t count, uint32_t tick); void destroy();
A SysEx handler is optional and goes third, beside process. The mode also carries HANDLES_SYSEX in its build declaration. Its shape is:
bool on_sysex(uint8_t port, const uint8_t* data, uint16_t len, uint8_t flags);
Returning true takes the message, so it is not sent on. Returning false lets it continue to the routed outputs.
It is called exactly once per mode, alongside OP_MODE_REGISTER_UI for a custom UI.
| #define OP_MODE_REGISTER_UI | ( | render_fn, | |
| gesture_fn ) |
Export a custom-UI mode's render and gesture hooks.
Optional, and used in addition to OP_MODE_REGISTER. Pass your render and gesture functions:
void render();
void gesture(uint8_t control, op::Gesture gesture,
op::GestureType type, int16_t value);
A mode that omits this is declarative-only: the firmware renders its parameter screen for you.