From b6500cddffb984bcafad94579077371d10147958 Mon Sep 17 00:00:00 2001 From: Stefano D'Angelo Date: Sat, 11 May 2024 11:30:39 +0200 Subject: [PATCH] some test gui work, lv2 port notifications start to work --- templates/lv2/src/lv2.c | 12 +++- templates/vst3/src/data.h | 2 +- test/plugin.h | 127 +++++++++++++++++++++++++++++++++++--- 3 files changed, 130 insertions(+), 11 deletions(-) diff --git a/templates/lv2/src/lv2.c b/templates/lv2/src/lv2.c index d23b010..71756be 100644 --- a/templates/lv2/src/lv2.c +++ b/templates/lv2/src/lv2.c @@ -325,8 +325,18 @@ static void ui_cleanup(LV2UI_Handle handle) { plugin_ui_free((plugin_ui *)handle); } +#define CONTROL_INPUT_INDEX_OFFSET ( \ + DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N \ + + DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N \ + + DATA_PRODUCT_MIDI_INPUTS_N \ + + DATA_PRODUCT_MIDI_OUTPUTS_N ) +#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) { - //TODO + 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)); + else + plugin_ui_set_parameter((plugin_ui *)handle, param_out_index[port_index - CONTROL_OUTPUT_INDEX_OFFSET], *((float *)buffer)); } static int ui_idle(LV2UI_Handle handle) { diff --git a/templates/vst3/src/data.h b/templates/vst3/src/data.h index fa7defc..7334af7 100644 --- a/templates/vst3/src/data.h +++ b/templates/vst3/src/data.h @@ -216,7 +216,7 @@ static struct { #endif {{?it.product.parameters.find(x => x.isLatency)}} -#define DATA_PARAM_LATENCY_INDEX {{=it.product.parameters.find(x => x.isLatency).paramIndex}} +#define DATA_PARAM_LATENCY_INDEX {{=it.product.parameters.find(x => x.isLatency).paramIndex}} {{?}} {{?it.product.ui}} diff --git a/test/plugin.h b/test/plugin.h index c92520e..72fb8ad 100644 --- a/test/plugin.h +++ b/test/plugin.h @@ -127,21 +127,107 @@ typedef struct { void * widget; PuglWorld * world; PuglView * view; + + float gain; + float delay; + float cutoff; + char bypass; + float y_z1; } plugin_ui; +#define WIDTH 600.0 +#define HEIGHT 400.0 +#define RATIO (WIDTH / HEIGHT) +#define INV_RATIO (HEIGHT / WIDTH) + static void plugin_ui_get_default_size(uint32_t *width, uint32_t *height) { - *width = 600; - *height = 400; + *width = WIDTH; + *height = HEIGHT; +} + +static void plugin_ui_draw(plugin_ui *instance) { + PuglRect frame = puglGetFrame(instance->view); + 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; + } else { + w = fw; + h = INV_RATIO * fw; + x = 0.0; + y = (fh - h) / 2; + } + + cairo_t *cr = (cairo_t *)puglGetContext(instance->view); + + cairo_set_line_width(cr, 0.005 * h); + + cairo_set_source_rgb(cr, 0, 0, 0); + cairo_paint(cr); + + cairo_set_source_rgb(cr, 0.2, 0.2, 0.2); + cairo_rectangle(cr, x, y, w, h); + cairo_fill(cr); + + cairo_set_source_rgb(cr, 0.1, 0.1, 0.1); + cairo_rectangle(cr, x + 0.1 * w, y + 0.15 * h, 0.8 * w, 0.1 * h); + cairo_fill(cr); + cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); + cairo_rectangle(cr, x + 0.1 * w, y + 0.15 * h, 0.8 * w * instance->gain, 0.1 * h); + cairo_fill(cr); + cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); + cairo_rectangle(cr, x + 0.1 * w, y + 0.15 * h, 0.8 * w, 0.1 * h); + cairo_stroke(cr); + + cairo_set_source_rgb(cr, 0.1, 0.1, 0.1); + cairo_rectangle(cr, x + 0.1 * w, y + 0.3 * h, 0.8 * w, 0.1 * h); + cairo_fill(cr); + cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); + cairo_rectangle(cr, x + 0.1 * w, y + 0.3 * h, 0.8 * w * instance->delay, 0.1 * h); + cairo_fill(cr); + cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); + cairo_rectangle(cr, x + 0.1 * w, y + 0.3 * h, 0.8 * w, 0.1 * h); + cairo_stroke(cr); + + cairo_set_source_rgb(cr, 0.1, 0.1, 0.1); + cairo_rectangle(cr, x + 0.1 * w, y + 0.45 * h, 0.8 * w, 0.1 * h); + cairo_fill(cr); + cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); + cairo_rectangle(cr, x + 0.1 * w, y + 0.45 * h, 0.8 * w * instance->cutoff, 0.1 * h); + cairo_fill(cr); + cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); + cairo_rectangle(cr, x + 0.1 * w, y + 0.45 * h, 0.8 * w, 0.1 * h); + cairo_stroke(cr); + + if (instance->bypass) + cairo_set_source_rgb(cr, 1.0, 0, 0); + else + cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); + cairo_rectangle(cr, x + 0.4 * w, y + 0.6 * h, 0.2 * w, 0.1 * h); + cairo_fill(cr); + + cairo_set_source_rgb(cr, 0.1, 0.1, 0.1); + cairo_rectangle(cr, x + 0.1 * w, y + 0.75 * h, 0.8 * w, 0.1 * h); + cairo_fill(cr); + + 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_EXPOSE: - { - cairo_t *cr = (cairo_t *)puglGetContext(view); - cairo_set_source_rgb(cr, 1, 0.5, 0); - cairo_paint(cr); - } + plugin_ui_draw((plugin_ui *)puglGetHandle(view)); break; default: break; @@ -155,10 +241,10 @@ static plugin_ui *plugin_ui_create(char has_parent, void *parent) { return NULL; instance->world = puglNewWorld(PUGL_MODULE, 0); instance->view = puglNewView(instance->world); - puglSetSizeHint(instance->view, PUGL_DEFAULT_SIZE, 600, 400); + puglSetSizeHint(instance->view, PUGL_DEFAULT_SIZE, WIDTH, HEIGHT); puglSetViewHint(instance->view, PUGL_RESIZABLE, PUGL_TRUE); puglSetBackend(instance->view, puglCairoBackend()); - PuglRect frame = { 0, 0, 600, 400 }; + PuglRect frame = { 0, 0, WIDTH, HEIGHT }; puglSetFrame(instance->view, frame); puglSetEventFunc(instance->view, plugin_ui_on_event); if (has_parent) @@ -169,6 +255,7 @@ static plugin_ui *plugin_ui_create(char has_parent, void *parent) { return NULL; } puglShow(instance->view, PUGL_SHOW_RAISE); + puglSetHandle(instance->view, instance); instance->widget = (void *)puglGetNativeView(instance->view); return instance; } @@ -183,4 +270,26 @@ static void plugin_ui_idle(plugin_ui *instance) { puglUpdate(instance->world, 0); } +static void plugin_ui_set_parameter(plugin_ui *instance, size_t index, float value) { + switch (index) { + case 0: + instance->gain = 0.0125f * value + 0.75f; + break; + case 1: + instance->delay = 0.001f * value; + break; + case 2: + // (bad) approx log unmap + instance->cutoff = (1.0326554320337176f * value - 20.65310864067435f) / (value + 632.4555320336754f); + break; + case 3: + instance->bypass = value >= 0.5f; + break; + case 4: + instance->y_z1 = 0.5f * value + 0.5f; + break; + } + puglPostRedisplay(instance->view); +} + #endif