xtc/include/xtc/xtc_plugin.h

134 lines
9.2 KiB
C
Raw Normal View History

#ifndef XTC_PLUGIN_H
#define XTC_PLUGIN_H
#include "xtc_processor.h"
#ifdef __cplusplus
extern "C" {
#endif
2026-10-28 17:16:01 +01:00
typedef enum { XTC_PLUGIN_LADSPA = 0, XTC_PLUGIN_CLAP, XTC_PLUGIN_VST2, XTC_PLUGIN_VST3, XTC_PLUGIN_BUILTIN } xtc_plugin_format;
/* Internal device indices: 0 Soft Keys, 1 Sub Bass, 2 Delay, 3 Reverb,
* 4 Sample Player, 5 Stereo Delay, 6 Stereo Reverb. */
2026-10-28 17:16:01 +01:00
#define XTC_BUILTIN_PATH "/xtc/internal"
const char *xtc_plugin_format_name(xtc_plugin_format format);
#define XTC_PLUGIN_CONTROLS 16U
#define XTC_PLUGIN_POINTS 32U
/* Absolute project ticks. Mode belongs to segment starting at this point:
* 0 linear, 1 hold/step. Outside a lane hold first/last; later ticks win when
* sample rounding collides. Integer/toggle controls require mode 1. */
typedef struct { uint64_t tick; unsigned int port, step; float value; } xtc_plugin_point;
/* Plain copied model: no library handles or callback pointers. Absolute trusted
2026-10-28 17:16:01 +01:00
* binary path (or reserved XTC_BUILTIN_PATH), identity/label verified on compile.
* Controls are LADSPA port indices; modern effects use default configuration
* with zero controls/points. Initialize the complete struct to zero. */
typedef struct {
char path[512], label[64];
xtc_plugin_format format;
char sample_path[512]; /* Internal sampler WAV reference; empty for other devices. */
char identifier[128]; /* CLAP stable ID / VST3 class hex; empty for LADSPA/VST2. */
unsigned int index, unique_id, inputs, control_count;
2026-10-28 17:16:01 +01:00
unsigned int instrument; /* Zero-input note instrument; track binding only. */
unsigned int ports[XTC_PLUGIN_CONTROLS];
float values[XTC_PLUGIN_CONTROLS];
unsigned int tempo, point_count; /* milli-BPM, 20000..300000 */
xtc_plugin_point points[XTC_PLUGIN_POINTS];
} xtc_plugin_spec;
/* Atomic versioned metadata presets; load never executes plugin code and
* preserves out on error. Modules are verified only when adopting playback. */
#define XTC_TRACK_INSERTS 8U
typedef struct { xtc_plugin_spec plugin; unsigned int enabled; float wet; } xtc_track_insert;
typedef struct { size_t count; float output_gain; xtc_track_insert slots[XTC_TRACK_INSERTS]; } xtc_track_chain;
/* Original internal-device starting points: 0 Slapback, 1 Dub Echo,
* 2 Ambient Space. Name returns NULL for an unknown index. No modules opened;
* template errors preserve out. Delay times are milliseconds, not beat sync. */
const char *xtc_track_chain_template_name(unsigned int index);
xtc_result xtc_track_chain_template(unsigned int index,unsigned int tempo,xtc_track_chain *out);
/* Copies the selected slot immediately after itself, preserving all metadata.
* Input/output may alias; errors preserve output. */
xtc_result xtc_track_chain_duplicate(const xtc_track_chain *chain,size_t index,xtc_track_chain *out);
/* Pure metadata operations, preserving output gain; aliases accepted and errors
* preserve out. Enabling missing plugins can fail later at plan preparation. */
typedef enum {XTC_CHAIN_ENABLE_ALL,XTC_CHAIN_BYPASS_ALL,XTC_CHAIN_CLEAR} xtc_chain_action;
xtc_result xtc_track_chain_bulk(const xtc_track_chain *chain,xtc_chain_action action,xtc_track_chain *out);
xtc_result xtc_track_chain_preset_save(const xtc_track_chain *chain,const char *path);
xtc_result xtc_track_chain_preset_load(const char *path,xtc_track_chain *out);
/* Metadata only; control thread. Empty chain has unity output. No module is
* opened here. Nonempty chains are mono effects on non-bus tracks. */
/* Allocates the exact serial/parallel graph used by playback. Caller owns it. */
xtc_result xtc_track_chain_graph(const xtc_track_chain *chain,xtc_graph **out);
xtc_result xtc_track_chain_validate(const xtc_track_chain *chain);
xtc_result xtc_project_get_chain(const xtc_project *project,uint64_t track,xtc_track_chain *out);
xtc_result xtc_project_set_chain(xtc_project *project,uint64_t track,const xtc_track_chain *chain);
/* Copied discovery metadata, never descriptor/module pointers. Modern adapters
* currently expose the name only (zero controls). LADSPA provides
* no standardized units; unit is empty. Flags describe input control hints. */
#define XTC_PLUGIN_INTEGER 1U
#define XTC_PLUGIN_TOGGLED 2U
#define XTC_PLUGIN_LOGARITHMIC 4U
#define XTC_PLUGIN_SAMPLE_RATE 8U
#define XTC_PLUGIN_BOUNDED_BELOW 16U
#define XTC_PLUGIN_BOUNDED_ABOVE 32U
typedef struct {
char name[128], maker[128], copyright[128];
unsigned int hard_realtime;
xtc_parameter_info parameters[XTC_PLUGIN_CONTROLS];
unsigned int flags[XTC_PLUGIN_CONTROLS];
} xtc_plugin_details;
/* Control-thread identity/layout verification and copied human-readable hints. */
xtc_result xtc_plugin_describe(const xtc_plugin_spec *spec, double rate, xtc_plugin_details *out);
/* Reset static values to defaults, removing automation for the chosen port.
* UINT32_MAX resets all controls. Failure leaves spec unchanged. */
xtc_result xtc_plugin_reset(xtc_plugin_spec *spec, double rate, unsigned int port);
/* Replace identity/controls at a stable node ID; only identical audio layouts
* are accepted, preserving all wires. Metadata-only; compile before adoption. */
xtc_result xtc_graph_replace_plugin(xtc_graph *graph, size_t id, const xtc_plugin_spec *spec);
typedef struct xtc_plugin xtc_plugin;
/* Serialized control/main thread: service CLAP callback requests. */
void xtc_plugin_idle(void);
/* Serialized main/control thread only (also create/destroy/idle). Probe explicitly
2026-11-06 18:13:49 +01:00
* enumerates a Linux binary or conventional .vst3 bundle by descriptor index;
* NOT_FOUND means end, UNSUPPORTED means descriptor/layout unsupported. Loading
* trusted libraries can execute arbitrary constructors. Never probe in audio. */
xtc_result xtc_plugin_probe_format(xtc_plugin_format format, const char *path, unsigned int index, double rate, xtc_plugin_spec *out);
/* Auto-detect exported entry point; may execute module constructors. */
xtc_result xtc_plugin_probe(const char *path, unsigned int index, double rate, xtc_plugin_spec *out);
/* Control-thread parameter names, computed ranges/defaults at this sample rate.
* Output has spec->control_count entries; IDs are LADSPA port indices. */
xtc_result xtc_plugin_parameters(const xtc_plugin_spec *spec, double rate, xtc_parameter_info out[XTC_PLUGIN_CONTROLS]);
/* Metadata-only validation: never opens libraries. */
xtc_result xtc_plugin_spec_validate(const xtc_plugin_spec *spec);
xtc_result xtc_plugin_create(const xtc_plugin_spec *spec, double rate, size_t frames, xtc_plugin **out);
/* Single audio owner or quiescent control owner. Internal state resets in bounded
* constant work; external-plugin history remains retained. No allocation/I/O. */
void xtc_plugin_reset_history(xtc_plugin *plugin);
size_t xtc_plugin_sample_frames(const xtc_plugin *plugin);
size_t xtc_plugin_asset_issues(const xtc_plugin *plugin);
void xtc_plugin_destroy(xtc_plugin *plugin); /* control, after quiescence */
/* Single audio owner. No loading/allocation/I/O in host process; trusted run()
* must obey realtime rules. No MIDI; max one mono input and one mono output.
* Transport reset retains LADSPA delay history (no realtime reset contract). */
/* Instruments: sorted bounded MIDI, mono output, single audio owner. */
2026-11-06 18:13:49 +01:00
/* Absolute sample position supports instrument parameter automation and seek.
* VST3 receives this clock plus the prepared spec tempo in its process context. */
xtc_result xtc_plugin_process_midi_at(xtc_plugin *plugin, const xtc_midi_event *events, size_t count, float *output, size_t frames, uint64_t position);
/* Control-thread preset files use a versioned single-instrument project container.
* Load is transactional, validates metadata and never loads executable modules. */
xtc_result xtc_plugin_preset_save(const xtc_plugin_spec *spec, const char *path);
xtc_result xtc_plugin_preset_load(const char *path, xtc_plugin_spec *out);
xtc_result xtc_plugin_process_midi(xtc_plugin *plugin, const xtc_midi_event *events, size_t count, float *output, size_t frames);
/* Metadata-only track assignment. NULL restores built-in sine. Assignment ensures
* an instrument-source graph route transactionally. Missing modules stay saved. */
xtc_result xtc_project_set_instrument(xtc_project *project, uint64_t track, const xtc_plugin_spec *spec);
xtc_result xtc_project_get_instrument(const xtc_project *project, uint64_t track, xtc_plugin_spec *out);
xtc_result xtc_project_set_live_instrument(xtc_project *project, uint64_t track);
xtc_result xtc_project_get_live_instrument(const xtc_project *project, uint64_t *track);
/* Coupled stereo internal effects (indices 5/6); channels may be in-place,
* output channels must be distinct. NULL right output renders a mono fold-down. */
xtc_result xtc_plugin_process_stereo_at(xtc_plugin *plugin,const float *left,const float *right,float *out,float *out_right,size_t frames,uint64_t position);
xtc_result xtc_plugin_process_at(xtc_plugin *plugin, const float *input, float *output, size_t frames, uint64_t position);
xtc_result xtc_plugin_process(xtc_plugin *plugin, const float *input, float *output, size_t frames);
xtc_result xtc_graph_add_plugin(xtc_graph *graph, const xtc_plugin_spec *spec, size_t *id);
xtc_result xtc_graph_get_plugin(const xtc_graph *graph, size_t id, xtc_plugin_spec *out);
xtc_result xtc_graph_set_plugin(xtc_graph *graph, size_t id, const xtc_plugin_spec *spec);
#ifdef __cplusplus
}
#endif
#endif