lv2 plugin parameter write cb in place
This commit is contained in:
parent
b6500cddff
commit
df88cc213e
@ -68,4 +68,10 @@ static uint32_t param_out_index[DATA_PRODUCT_CONTROL_OUTPUTS_N] = {
|
||||
{{?it.lv2.ui}}
|
||||
#define DATA_LV2_UI_URI "{{=it.tibia.CGetUTF8StringLiteral(it.tibia.lv2.expandURI(it.lv2.ui.uri))}}"
|
||||
#define DATA_UI_USER_RESIZABLE {{=it.product.ui.userResizable ? 1 : 0}}
|
||||
|
||||
#if DATA_PRODUCT_CONTROL_INPUTS_N > 0
|
||||
static uint32_t index_to_param[DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N] = {
|
||||
{{~it.tibia.lv2.ports.filter(x => x.type == "control").map((e, i) => ({ i: i, pi: e.paramIndex })).sort((a, b) => a.pi - b.pi) :p}}{{=p.i + it.tibia.lv2.ports.filter(x => x.type != "control").length}}, {{~}}
|
||||
};
|
||||
#endif
|
||||
{{?}}
|
||||
|
@ -21,6 +21,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
void * handle;
|
||||
void (*set_parameter)(void *handle, size_t index, float value);
|
||||
} plugin_ui_callbacks;
|
||||
|
||||
#define TEMPLATE_HAS_UI
|
||||
#include "data.h"
|
||||
#include "plugin.h"
|
||||
@ -267,7 +272,6 @@ static void run(LV2_Handle instance, uint32_t sample_count) {
|
||||
_MM_SET_FLUSH_ZERO_MODE(flush_zero_mode);
|
||||
_MM_SET_DENORMALS_ZERO_MODE(denormals_zero_mode);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void cleanup(LV2_Handle instance) {
|
||||
@ -294,13 +298,17 @@ LV2_SYMBOL_EXPORT const LV2_Descriptor * lv2_descriptor(uint32_t index) {
|
||||
}
|
||||
|
||||
#ifdef PLUGIN_UI
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
typedef struct {
|
||||
Display * display;
|
||||
Window window;
|
||||
plugin_ui * ui;
|
||||
LV2UI_Write_Function write;
|
||||
LV2UI_Controller controller;
|
||||
} ui_instance;
|
||||
|
||||
static void ui_set_parameter_cb(void *handle, size_t index, float value) {
|
||||
ui_instance *instance = (ui_instance *)handle;
|
||||
instance->write(instance->controller, index_to_param[index], sizeof(float), 0, &value);
|
||||
}
|
||||
|
||||
static LV2UI_Handle ui_instantiate(const LV2UI_Descriptor * descriptor, const char * plugin_uri, const char * bundle_path, LV2UI_Write_Function write_function, LV2UI_Controller controller, LV2UI_Widget * widget, const LV2_Feature * const * features) {
|
||||
char has_parent = 0;
|
||||
void *parent = NULL;
|
||||
@ -312,17 +320,33 @@ static LV2UI_Handle ui_instantiate(const LV2UI_Descriptor * descriptor, const ch
|
||||
// TODO...
|
||||
}
|
||||
|
||||
plugin_ui *instance = plugin_ui_create(has_parent, parent);
|
||||
ui_instance *instance = malloc(sizeof(ui_instance));
|
||||
if (instance == NULL) {
|
||||
*widget = NULL;
|
||||
return NULL;
|
||||
}
|
||||
*widget = instance->widget;
|
||||
|
||||
plugin_ui_callbacks cbs = {
|
||||
/* .handle = */ (void *)instance,
|
||||
/* .set_parameter = */ ui_set_parameter_cb
|
||||
};
|
||||
instance->write = write_function;
|
||||
instance->controller = controller;
|
||||
instance->ui = plugin_ui_create(has_parent, parent, &cbs);
|
||||
if (instance->ui == NULL) {
|
||||
free(instance);
|
||||
*widget = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*widget = instance->ui->widget;
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void ui_cleanup(LV2UI_Handle handle) {
|
||||
plugin_ui_free((plugin_ui *)handle);
|
||||
ui_instance *instance = (ui_instance *)handle;
|
||||
plugin_ui_free(instance->ui);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
#define CONTROL_INPUT_INDEX_OFFSET ( \
|
||||
@ -333,14 +357,16 @@ static void ui_cleanup(LV2UI_Handle handle) {
|
||||
#define CONTROL_OUTPUT_INDEX_OFFSET (CONTROL_INPUT_INDEX_OFFSET + DATA_PRODUCT_CONTROL_INPUTS_N)
|
||||
|
||||
static void ui_port_event(LV2UI_Handle handle, uint32_t port_index, uint32_t buffer_size, uint32_t format, const void * buffer) {
|
||||
ui_instance *instance = (ui_instance *)handle;
|
||||
if (port_index < CONTROL_OUTPUT_INDEX_OFFSET)
|
||||
plugin_ui_set_parameter((plugin_ui *)handle, param_data[port_index - CONTROL_INPUT_INDEX_OFFSET].index, *((float *)buffer));
|
||||
plugin_ui_set_parameter(instance->ui, param_data[port_index - CONTROL_INPUT_INDEX_OFFSET].index, *((float *)buffer));
|
||||
else
|
||||
plugin_ui_set_parameter((plugin_ui *)handle, param_out_index[port_index - CONTROL_OUTPUT_INDEX_OFFSET], *((float *)buffer));
|
||||
plugin_ui_set_parameter(instance->ui, param_out_index[port_index - CONTROL_OUTPUT_INDEX_OFFSET], *((float *)buffer));
|
||||
}
|
||||
|
||||
static int ui_idle(LV2UI_Handle handle) {
|
||||
plugin_ui_idle((plugin_ui *)handle);
|
||||
ui_instance *instance = (ui_instance *)handle;
|
||||
plugin_ui_idle(instance->ui);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -124,15 +124,24 @@ static void plugin_midi_msg_in(plugin *instance, size_t index, const uint8_t * d
|
||||
# include <cairo.h>
|
||||
|
||||
typedef struct {
|
||||
void * widget;
|
||||
PuglWorld * world;
|
||||
PuglView * view;
|
||||
void * widget;
|
||||
PuglWorld * world;
|
||||
PuglView * view;
|
||||
|
||||
float gain;
|
||||
float delay;
|
||||
float cutoff;
|
||||
char bypass;
|
||||
float y_z1;
|
||||
double fw;
|
||||
double fh;
|
||||
double x;
|
||||
double y;
|
||||
double w;
|
||||
double h;
|
||||
|
||||
float gain;
|
||||
float delay;
|
||||
float cutoff;
|
||||
char bypass;
|
||||
float y_z1;
|
||||
|
||||
plugin_ui_callbacks cbs;
|
||||
} plugin_ui;
|
||||
|
||||
#define WIDTH 600.0
|
||||
@ -145,27 +154,32 @@ static void plugin_ui_get_default_size(uint32_t *width, uint32_t *height) {
|
||||
*height = HEIGHT;
|
||||
}
|
||||
|
||||
static void plugin_ui_draw(plugin_ui *instance) {
|
||||
static void plugin_ui_update_geometry(plugin_ui *instance) {
|
||||
PuglRect frame = puglGetFrame(instance->view);
|
||||
instance->fw = frame.width;
|
||||
instance->fh = frame.height;
|
||||
if (frame.width == 0 || frame.height == 0)
|
||||
return;
|
||||
|
||||
double x, y, w, h;
|
||||
double fw = frame.width;
|
||||
double fh = frame.height;
|
||||
if (fw / fh > RATIO) {
|
||||
w = RATIO * fh;
|
||||
h = fh;
|
||||
x = (fw - w) / 2;
|
||||
y = 0.0;
|
||||
if (instance->fw / instance->fh > RATIO) {
|
||||
instance->w = RATIO * instance->fh;
|
||||
instance->h = instance->fh;
|
||||
instance->x = 0.5 * (instance->fw - instance->w);
|
||||
instance->y = 0.0;
|
||||
} else {
|
||||
w = fw;
|
||||
h = INV_RATIO * fw;
|
||||
x = 0.0;
|
||||
y = (fh - h) / 2;
|
||||
instance->w = instance->fw;
|
||||
instance->h = INV_RATIO * instance->fw;
|
||||
instance->x = 0.0;
|
||||
instance->y = 0.5 * (instance->fh - instance->h);
|
||||
}
|
||||
}
|
||||
|
||||
static void plugin_ui_draw(plugin_ui *instance) {
|
||||
cairo_t *cr = (cairo_t *)puglGetContext(instance->view);
|
||||
double x = instance->x;
|
||||
double y = instance->y;
|
||||
double w = instance->w;
|
||||
double h = instance->h;
|
||||
|
||||
cairo_set_line_width(cr, 0.005 * h);
|
||||
|
||||
@ -220,14 +234,39 @@ static void plugin_ui_draw(plugin_ui *instance) {
|
||||
cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
|
||||
cairo_rectangle(cr, x + 0.1 * w, y + 0.75 * h, 0.8 * w * instance->y_z1, 0.1 * h);
|
||||
cairo_fill(cr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PuglStatus plugin_ui_on_event(PuglView *view, const PuglEvent *event) {
|
||||
switch (event->type) {
|
||||
case PUGL_CONFIGURE:
|
||||
{
|
||||
plugin_ui *instance = (plugin_ui *)puglGetHandle(view);
|
||||
plugin_ui_update_geometry(instance);
|
||||
}
|
||||
break;
|
||||
case PUGL_BUTTON_RELEASE:
|
||||
{
|
||||
plugin_ui *instance = (plugin_ui *)puglGetHandle(view);
|
||||
PuglRect frame = puglGetFrame(view);
|
||||
const PuglButtonEvent *ev = (const PuglButtonEvent *)event;
|
||||
double x = instance->x;
|
||||
double y = instance->y;
|
||||
double w = instance->w;
|
||||
double h = instance->h;
|
||||
|
||||
if (ev->x >= x + 0.1 * w && ev->x <= x + 0.9 * w
|
||||
&& ev->y >= y + 0.15 * h && ev->y <= y + 0.25 * h) {
|
||||
instance->gain = (float)((ev->x - (x + 0.1 * w)) / (0.8 * w));
|
||||
instance->cbs.set_parameter(instance->cbs.handle, 0, -60.f + 80.f * instance->gain);
|
||||
puglPostRedisplay(instance->view);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PUGL_EXPOSE:
|
||||
plugin_ui_draw((plugin_ui *)puglGetHandle(view));
|
||||
{
|
||||
plugin_ui *instance = (plugin_ui *)puglGetHandle(view);
|
||||
plugin_ui_draw(instance);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -235,7 +274,7 @@ static PuglStatus plugin_ui_on_event(PuglView *view, const PuglEvent *event) {
|
||||
return PUGL_SUCCESS;
|
||||
}
|
||||
|
||||
static plugin_ui *plugin_ui_create(char has_parent, void *parent) {
|
||||
static plugin_ui *plugin_ui_create(char has_parent, void *parent, plugin_ui_callbacks *cbs) {
|
||||
plugin_ui *instance = malloc(sizeof(plugin_ui));
|
||||
if (instance == NULL)
|
||||
return NULL;
|
||||
@ -257,6 +296,7 @@ static plugin_ui *plugin_ui_create(char has_parent, void *parent) {
|
||||
puglShow(instance->view, PUGL_SHOW_RAISE);
|
||||
puglSetHandle(instance->view, instance);
|
||||
instance->widget = (void *)puglGetNativeView(instance->view);
|
||||
instance->cbs = *cbs;
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user