Commit 7e50ba3f authored by ale's avatar ale

Add UI controls for humanizer

State restore still doesn't work though.
parent 3a4175dc
......@@ -479,7 +479,7 @@ static char *resolve_symlink(const char *filename) {
}
int drumkit_load(struct drumkit *kit, const char *filename, int target_samplerate) {
char *basedir = NULL;
char *basedir = NULL, *resolved_filename = NULL;
xmlDocPtr doc = NULL;
xmlNsPtr ns = NULL;
xmlNodePtr root_element = NULL;
......@@ -490,8 +490,8 @@ int drumkit_load(struct drumkit *kit, const char *filename, int target_samplerat
// Resolve symlinks because sometimes (i.e. in presets) we get sent
// a symbolic link to the actual drumkit.xml, which messes up the
// relative filenames of the samples.
filename = resolve_symlink(filename);
basedir = path_dirname(filename);
resolved_filename = resolve_symlink(filename);
basedir = path_dirname(resolved_filename);
kit->instruments = NULL;
doc = xmlParseFile(filename);
......@@ -536,11 +536,11 @@ int drumkit_load(struct drumkit *kit, const char *filename, int target_samplerat
kit->num_instruments = n;
}
kit->path = strdup(filename);
kit->path = strdup(resolved_filename);
fix_midi_notes(kit);
cleanup:
free(filename);
free(resolved_filename);
free(basedir);
if (xpathObj) {
xmlXPathFreeObject(xpathObj);
......
......@@ -81,6 +81,55 @@
lv2:maximum 192000 ;
lv2:portProperty lv2:reportsLatency, lv2:integer ;
units:unit units:frame ;
] , [
a lv2:InputPort ,
lv2:ControlPort ;
lv2:index 5 ;
lv2:symbol "hu_latency_max" ;
lv2:name "Humanizer Latency Max" ;
lv2:default 0.0 ;
lv2:minimum 0.0 ;
lv2:maximum 400.0 ;
units:unit units:ms ;
] , [
a lv2:InputPort ,
lv2:ControlPort ;
lv2:index 6 ;
lv2:symbol "hu_latency_stddev" ;
lv2:name "Humanizer Latency StdDev" ;
lv2:default 0.0 ;
lv2:minimum 0.0 ;
lv2:maximum 100.0 ;
units:unit units:ms ;
] , [
a lv2:InputPort ,
lv2:ControlPort ;
lv2:index 7 ;
lv2:symbol "hu_latency_laidback" ;
lv2:name "Humanizer Latency LaidBack" ;
lv2:default 0.0 ;
lv2:minimum 0.0 ;
lv2:maximum 100.0 ;
units:unit units:ms ;
] , [
a lv2:InputPort ,
lv2:ControlPort ;
lv2:index 8 ;
lv2:symbol "hu_latency_regain" ;
lv2:name "Humanizer Latency Regain" ;
lv2:default 0.0 ;
lv2:minimum 0.0 ;
lv2:maximum 100.0 ;
units:unit units:ms ;
] , [
a lv2:InputPort ,
lv2:ControlPort ;
lv2:index 9 ;
lv2:symbol "hu_velocity_stddev" ;
lv2:name "Humanizer Velocity StdDev" ;
lv2:default 0.0 ;
lv2:minimum 0.0 ;
lv2:maximum 1.0 ;
];
state:state [
<http://lv2.incal.net/plugins/hydrumkit#drumkit> </usr/share/hydrogen/data/drumkits/GMkit/drumkit.xml>
......
......@@ -22,14 +22,9 @@
#include "engine/sampler.h"
#include "atom_sink.h"
#include "ports.h"
#include "uris.h"
#define SAMPLER_CONTROL 0
#define SAMPLER_NOTIFY 1
#define SAMPLER_OUT_L 2
#define SAMPLER_OUT_R 3
#define SAMPLER_LATENCY 4
#define NUM_VOICES 64
struct sampler_plugin {
......@@ -42,6 +37,7 @@ struct sampler_plugin {
float *output_port_l;
float *output_port_r;
float *output_latency;
float *input_ports[PORT_LAST];
LV2_Atom_Forge_Frame notify_frame;
LV2_Atom_Forge forge;
......@@ -52,6 +48,7 @@ struct sampler_plugin {
struct sampler *sampler;
int activated;
int send_settings_to_ui;
uint32_t frame_offset;
int samplerate;
};
......@@ -128,22 +125,25 @@ static void deactivate(LV2_Handle instance) {
static void connect_port(LV2_Handle instance, uint32_t port, void *data) {
struct sampler_plugin *plugin = (struct sampler_plugin *)instance;
switch (port) {
case SAMPLER_CONTROL:
case PORT_CONTROL:
plugin->control_port = (const LV2_Atom_Sequence *)data;
break;
case SAMPLER_NOTIFY:
case PORT_NOTIFY:
plugin->notify_port = (LV2_Atom_Sequence *)data;
break;
case SAMPLER_OUT_L:
case PORT_OUT_L:
plugin->output_port_l = (float *)data;
break;
case SAMPLER_OUT_R:
case PORT_OUT_R:
plugin->output_port_r = (float *)data;
break;
case SAMPLER_LATENCY:
case PORT_LATENCY:
plugin->output_latency = (float *)data;
break;
default:
if (port < PORT_LAST) {
plugin->input_ports[port] = (float *)data;
}
break;
}
}
......@@ -160,8 +160,11 @@ static LV2_Handle instantiate(const LV2_Descriptor *descriptor, double rate,
// Get host features
const char *missing = lv2_features_query(
features, LV2_LOG__log, &plugin->logger.log, false, LV2_URID__map,
&plugin->map, true, LV2_WORKER__schedule, &plugin->schedule, true, NULL);
features,
LV2_LOG__log, &plugin->logger.log, false,
LV2_URID__map, &plugin->map, true,
LV2_WORKER__schedule, &plugin->schedule, true,
NULL);
lv2_log_logger_set_map(&plugin->logger, plugin->map);
if (missing) {
lv2_log_error(&plugin->logger, "Missing feature <%s>\n", missing);
......@@ -246,8 +249,18 @@ static void handle_event(struct sampler_plugin *plugin, LV2_Atom_Event *ev) {
}
}
static void update_hsettings(struct sampler_plugin *plugin) {
// Apply settings to sampler.
plugin->hsettings.latency_max_ms = *plugin->input_ports[PORT_HUMANIZE_LATENCY_MAX];
plugin->hsettings.latency_stddev_ms = *plugin->input_ports[PORT_HUMANIZE_LATENCY_STDDEV];
plugin->hsettings.latency_laid_back_ms = *plugin->input_ports[PORT_HUMANIZE_LATENCY_LAID_BACK];
plugin->hsettings.latency_regain = *plugin->input_ports[PORT_HUMANIZE_LATENCY_REGAIN];
plugin->hsettings.velocity_stddev = *plugin->input_ports[PORT_HUMANIZE_VELOCITY_STDDEV];
}
static void render(struct sampler_plugin *plugin, uint32_t start,
uint32_t end) {
update_hsettings(plugin);
sampler_output(plugin->sampler,
plugin->output_port_l + start,
plugin->output_port_r + start,
......@@ -260,9 +273,31 @@ static void run(LV2_Handle instance, uint32_t sample_count) {
const uint32_t notify_capacity = plugin->notify_port->atom.size;
lv2_atom_forge_set_buffer(&plugin->forge, (uint8_t *)plugin->notify_port,
notify_capacity);
lv2_atom_forge_sequence_head(&plugin->forge, &plugin->notify_frame, 0);
if (plugin->send_settings_to_ui) {
plugin->send_settings_to_ui = 0;
// Forge container object of type 'ui_state'
LV2_Atom_Forge_Frame frame;
lv2_atom_forge_frame_time(&plugin->forge, 0);
lv2_atom_forge_object(&plugin->forge, &frame, 0, plugin->uris.ui_State);
// Add UI state as properties
lv2_atom_forge_key(&plugin->forge, plugin->uris.ui_hu_latency_max);
lv2_atom_forge_float(&plugin->forge, plugin->hsettings.latency_max_ms);
lv2_atom_forge_key(&plugin->forge, plugin->uris.ui_hu_latency_stddev);
lv2_atom_forge_float(&plugin->forge, plugin->hsettings.latency_stddev_ms);
lv2_atom_forge_key(&plugin->forge, plugin->uris.ui_hu_latency_laidback);
lv2_atom_forge_float(&plugin->forge, plugin->hsettings.latency_laid_back_ms);
lv2_atom_forge_key(&plugin->forge, plugin->uris.ui_hu_latency_regain);
lv2_atom_forge_float(&plugin->forge, plugin->hsettings.latency_regain);
lv2_atom_forge_key(&plugin->forge, plugin->uris.ui_hu_velocity_stddev);
lv2_atom_forge_float(&plugin->forge, plugin->hsettings.velocity_stddev);
lv2_atom_forge_pop(&plugin->forge, &frame);
}
// Incrementally process control events and render audio data.
plugin->frame_offset = 0;
LV2_ATOM_SEQUENCE_FOREACH(plugin->control_port, ev) {
render(plugin, plugin->frame_offset, ev->time.frames);
......@@ -350,7 +385,6 @@ static LV2_State_Status restore(LV2_Handle instance,
return LV2_WORKER_ERR_UNKNOWN;
}
sampler_set_drumkit(plugin->sampler, new_kit);
} else {
LV2_Atom_Forge forge;
LV2_Atom *buf = (LV2_Atom *)calloc(1, strlen(path) + 128);
......@@ -366,6 +400,7 @@ static LV2_State_Status restore(LV2_Handle instance,
}
free((void *)path);
plugin->send_settings_to_ui = 1;
return LV2_STATE_SUCCESS;
}
......
#ifndef __plugin_ports_H
#define __plugin_ports_H 1
// Definitions for ports to match our LV2 TTL spec.
#define PORT_CONTROL 0
#define PORT_NOTIFY 1
#define PORT_OUT_L 2
#define PORT_OUT_R 3
#define PORT_LATENCY 4
#define PORT_HUMANIZE_LATENCY_MAX 5
#define PORT_HUMANIZE_LATENCY_STDDEV 6
#define PORT_HUMANIZE_LATENCY_LAID_BACK 7
#define PORT_HUMANIZE_LATENCY_REGAIN 8
#define PORT_HUMANIZE_VELOCITY_STDDEV 9
#define PORT_LAST 10
#endif
#include "uris.h"
#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
#include "lv2/lv2plug.in/ns/ext/atom/forge.h"
#include "lv2/lv2plug.in/ns/ext/atom/util.h"
......@@ -29,7 +27,8 @@
#include <string.h>
#include <sys/stat.h>
#define SAMPLER_UI_URI "http://lv2.incal.net/plugins/hydrumkit#ui"
#include "ports.h"
#include "uris.h"
#define KNOB_SIZE 32
......@@ -47,19 +46,21 @@ struct plugin_ui {
GtkWidget *load_dialog;
GtkWidget *button_box;
GtkWidget *box;
GtkWidget *humanizer_box;
GtkWidget *humanizer_button;
GtkWidget *humanizer_latency_max_knob;
GtkWidget *humanizer_latency_stddev_knob;
GtkWidget *humanizer_latency_laid_back_knob;
GtkWidget *humanizer_velocity_knob;
GtkWidget *humanize_box;
GtkWidget *humanize_button;
GtkWidget *humanize_latency_max_knob;
GtkWidget *humanize_latency_stddev_knob;
GtkWidget *humanize_latency_laid_back_knob;
GtkWidget *humanize_latency_regain_knob;
GtkWidget *humanize_velocity_stddev_knob;
GtkWidget *window; /* For optional show interface. */
int humanizer_enabled;
float humanizer_latency_max_value;
float humanizer_latency_stddev_value;
float humanizer_latency_laid_back_value;
float humanizer_velocity_value;
int humanize_enabled;
float humanize_latency_max_value;
float humanize_latency_stddev_value;
float humanize_latency_laid_back_value;
float humanize_latency_regain_value;
float humanize_velocity_stddev_value;
char *filename;
......@@ -103,27 +104,36 @@ static void on_load_dialog_response(GtkDialog *widget, gint response, void *hand
msg = (LV2_Atom *)write_set_file(&ui->forge, &ui->uris, filename,
strlen(filename));
ui->write(ui->controller, 0, lv2_atom_total_size(msg),
ui->write(ui->controller, PORT_CONTROL, lv2_atom_total_size(msg),
ui->uris.atom_eventTransfer, msg);
g_free(filename);
};
}
static void on_humanizer_button_click(GtkButton *widget, void *handle) {
#define WRITECONTROLVALUE(var, port) \
val = ui->humanize_enabled ? ui-> var : 0; \
ui->write(ui->controller, port, sizeof(float), 0, (const void *)&val)
static void write_control_values(struct plugin_ui *ui) {
float val;
WRITECONTROLVALUE(humanize_latency_max_value, PORT_HUMANIZE_LATENCY_MAX);
WRITECONTROLVALUE(humanize_latency_stddev_value, PORT_HUMANIZE_LATENCY_STDDEV);
WRITECONTROLVALUE(humanize_latency_laid_back_value, PORT_HUMANIZE_LATENCY_LAID_BACK);
WRITECONTROLVALUE(humanize_latency_regain_value, PORT_HUMANIZE_LATENCY_REGAIN);
WRITECONTROLVALUE(humanize_velocity_stddev_value, PORT_HUMANIZE_VELOCITY_STDDEV);
}
static void on_humanize_button_click(GtkButton *widget, void *handle) {
struct plugin_ui *ui = (struct plugin_ui *)handle;
ui->humanizer_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
printf("humanizer %s\n", ui->humanizer_enabled ? "enabled" : "disabled");
ui->humanize_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
write_control_values(ui);
}
static void on_humanizer_knob_change(KnobWidget *widget, void *handle) {
static void on_humanize_knob_change(KnobWidget *widget, void *handle) {
struct plugin_ui *ui = (struct plugin_ui *)handle;
printf("humanizer value change: latency=%g/%g/%g velocity=%g\n",
ui->humanizer_latency_max_value,
ui->humanizer_latency_stddev_value,
ui->humanizer_latency_laid_back_value,
ui->humanizer_velocity_value);
write_control_values(ui);
}
static int path_exists(const char *path) {
......@@ -172,7 +182,7 @@ static LV2UI_Handle instantiate(const LV2UI_Descriptor *descriptor,
gtk_orientable_set_orientation(GTK_ORIENTABLE(ui->box), GTK_ORIENTATION_VERTICAL);
ui->label = gtk_label_new("No drumkit loaded.");
ui->button_box = gtk_grid_new();
ui->humanizer_box = gtk_grid_new();
ui->humanize_box = gtk_grid_new();
// Create the file chooser (we use a custom GtkButton instead of the
// default GtkFileChooserButton because the latter takes way too
......@@ -208,16 +218,18 @@ static LV2UI_Handle instantiate(const LV2UI_Descriptor *descriptor,
}
// Create the humanizer controls.
ui->humanizer_button = gtk_check_button_new_with_label("Humanize");
ui->humanizer_latency_max_knob = knob_widget_new(&ui->humanizer_latency_max_value, KNOB_SIZE, 0);
ui->humanizer_latency_stddev_knob = knob_widget_new(&ui->humanizer_latency_stddev_value, KNOB_SIZE, 0);
ui->humanizer_latency_laid_back_knob = knob_widget_new(&ui->humanizer_latency_laid_back_value, KNOB_SIZE, 0);
ui->humanizer_velocity_knob = knob_widget_new(&ui->humanizer_velocity_value, KNOB_SIZE, 0);
g_signal_connect(ui->humanizer_button, "clicked", G_CALLBACK(on_humanizer_button_click), ui);
g_signal_connect(ui->humanizer_latency_max_knob, "value-changed", G_CALLBACK(on_humanizer_knob_change), ui);
g_signal_connect(ui->humanizer_latency_stddev_knob, "value-changed", G_CALLBACK(on_humanizer_knob_change), ui);
g_signal_connect(ui->humanizer_latency_laid_back_knob, "value-changed", G_CALLBACK(on_humanizer_knob_change), ui);
g_signal_connect(ui->humanizer_velocity_knob, "value-changed", G_CALLBACK(on_humanizer_knob_change), ui);
ui->humanize_button = gtk_check_button_new_with_label("Humanize");
ui->humanize_latency_max_knob = knob_widget_new(&ui->humanize_latency_max_value, KNOB_SIZE, 0);
ui->humanize_latency_stddev_knob = knob_widget_new(&ui->humanize_latency_stddev_value, KNOB_SIZE, 0);
ui->humanize_latency_laid_back_knob = knob_widget_new(&ui->humanize_latency_laid_back_value, KNOB_SIZE, 0);
ui->humanize_latency_regain_knob = knob_widget_new(&ui->humanize_latency_regain_value, KNOB_SIZE, 0);
ui->humanize_velocity_stddev_knob = knob_widget_new(&ui->humanize_velocity_stddev_value, KNOB_SIZE, 0);
g_signal_connect(ui->humanize_button, "clicked", G_CALLBACK(on_humanize_button_click), ui);
g_signal_connect(ui->humanize_latency_max_knob, "value-changed", G_CALLBACK(on_humanize_knob_change), ui);
g_signal_connect(ui->humanize_latency_stddev_knob, "value-changed", G_CALLBACK(on_humanize_knob_change), ui);
g_signal_connect(ui->humanize_latency_laid_back_knob, "value-changed", G_CALLBACK(on_humanize_knob_change), ui);
g_signal_connect(ui->humanize_latency_regain_knob, "value-changed", G_CALLBACK(on_humanize_knob_change), ui);
g_signal_connect(ui->humanize_velocity_stddev_knob, "value-changed", G_CALLBACK(on_humanize_knob_change), ui);
// Place all elements inside their containers.
gtk_container_set_border_width(GTK_CONTAINER(ui->box), 4);
......@@ -227,12 +239,13 @@ static LV2UI_Handle instantiate(const LV2UI_Descriptor *descriptor,
gtk_container_add(GTK_CONTAINER(ui->button_box), ui->load_button);
gtk_widget_set_hexpand(ui->load_button, FALSE);
gtk_container_add(GTK_CONTAINER(ui->box), ui->button_box);
gtk_container_add(GTK_CONTAINER(ui->humanizer_box), ui->humanizer_button);
gtk_container_add(GTK_CONTAINER(ui->humanizer_box), ui->humanizer_latency_max_knob);
gtk_container_add(GTK_CONTAINER(ui->humanizer_box), ui->humanizer_latency_stddev_knob);
gtk_container_add(GTK_CONTAINER(ui->humanizer_box), ui->humanizer_latency_laid_back_knob);
gtk_container_add(GTK_CONTAINER(ui->humanizer_box), ui->humanizer_velocity_knob);
gtk_container_add(GTK_CONTAINER(ui->box), ui->humanizer_box);
gtk_container_add(GTK_CONTAINER(ui->humanize_box), ui->humanize_button);
gtk_container_add(GTK_CONTAINER(ui->humanize_box), ui->humanize_latency_max_knob);
gtk_container_add(GTK_CONTAINER(ui->humanize_box), ui->humanize_latency_stddev_knob);
gtk_container_add(GTK_CONTAINER(ui->humanize_box), ui->humanize_latency_laid_back_knob);
gtk_container_add(GTK_CONTAINER(ui->humanize_box), ui->humanize_latency_regain_knob);
gtk_container_add(GTK_CONTAINER(ui->humanize_box), ui->humanize_velocity_stddev_knob);
gtk_container_add(GTK_CONTAINER(ui->box), ui->humanize_box);
g_signal_connect(ui->load_dialog, "response", G_CALLBACK(on_load_dialog_response), ui);
......@@ -257,17 +270,66 @@ static void cleanup(LV2UI_Handle handle) {
gtk_widget_destroy(ui->load_dialog);
gtk_widget_destroy(ui->load_button);
gtk_widget_destroy(ui->button_box);
gtk_widget_destroy(ui->humanizer_button);
gtk_widget_destroy(ui->humanizer_latency_max_knob);
gtk_widget_destroy(ui->humanizer_latency_stddev_knob);
gtk_widget_destroy(ui->humanizer_latency_laid_back_knob);
gtk_widget_destroy(ui->humanizer_velocity_knob);
gtk_widget_destroy(ui->humanizer_box);
gtk_widget_destroy(ui->humanize_button);
gtk_widget_destroy(ui->humanize_latency_max_knob);
gtk_widget_destroy(ui->humanize_latency_stddev_knob);
gtk_widget_destroy(ui->humanize_latency_laid_back_knob);
gtk_widget_destroy(ui->humanize_latency_regain_knob);
gtk_widget_destroy(ui->humanize_velocity_stddev_knob);
gtk_widget_destroy(ui->humanize_box);
gtk_widget_destroy(ui->box);
free(ui);
}
static int recv_ui_state(struct plugin_ui *ui, const LV2_Atom_Object *obj) {
const LV2_Atom *hu_latency_max_val = NULL;
const LV2_Atom *hu_latency_stddev_val = NULL;
const LV2_Atom *hu_latency_laidback_val = NULL;
const LV2_Atom *hu_latency_regain_val = NULL;
const LV2_Atom *hu_velocity_stddev_val = NULL;
const int n_props = lv2_atom_object_get(obj,
ui->uris.ui_hu_latency_max, &hu_latency_max_val,
ui->uris.ui_hu_latency_stddev, &hu_latency_stddev_val,
ui->uris.ui_hu_latency_laidback, &hu_latency_laidback_val,
ui->uris.ui_hu_latency_regain, &hu_latency_regain_val,
ui->uris.ui_hu_velocity_stddev, &hu_velocity_stddev_val,
NULL);
if (n_props != 5 ||
hu_latency_max_val->type != ui->uris.atom_Float ||
hu_latency_stddev_val->type != ui->uris.atom_Float ||
hu_latency_laidback_val->type != ui->uris.atom_Float ||
hu_latency_regain_val->type != ui->uris.atom_Float ||
hu_velocity_stddev_val->type != ui->uris.atom_Float) {
// Object does not have the required properties with correct types.
return 0;
}
// Get the values we need from the body of the property value atoms.
ui->humanize_latency_max_value = ((const LV2_Atom_Float *)hu_latency_max_val)->body;
ui->humanize_latency_stddev_value = ((const LV2_Atom_Float *)hu_latency_stddev_val)->body;
ui->humanize_latency_laid_back_value = ((const LV2_Atom_Float *)hu_latency_laidback_val)->body;
ui->humanize_latency_regain_value = ((const LV2_Atom_Float *)hu_latency_regain_val)->body;
ui->humanize_velocity_stddev_value = ((const LV2_Atom_Float *)hu_velocity_stddev_val)->body;
printf("received UI state update, huLat=%g/%g/%g/%g, huVel=%g\n",
ui->humanize_latency_max_value,
ui->humanize_latency_stddev_value,
ui->humanize_latency_laid_back_value,
ui->humanize_latency_regain_value,
ui->humanize_velocity_stddev_value);
// Update UI.
gtk_widget_queue_draw(ui->humanize_latency_max_knob);
gtk_widget_queue_draw(ui->humanize_latency_stddev_knob);
gtk_widget_queue_draw(ui->humanize_latency_laid_back_knob);
gtk_widget_queue_draw(ui->humanize_latency_regain_knob);
gtk_widget_queue_draw(ui->humanize_velocity_stddev_knob);
return 1;
}
// The drumkit "name" that we show to the user is just the basename of
// the drumkit directory.
static char *get_drumkit_label(const char *filename) {
......@@ -306,6 +368,10 @@ static void port_event(LV2UI_Handle handle, uint32_t port_index,
} else if (!path) {
lv2_log_warning(&ui->logger, "Set message has no path\n");
}
} else if (obj->body.otype == ui->uris.ui_State) {
if (!recv_ui_state(ui, obj)) {
lv2_log_error(&ui->logger, "Error receiving UI state\n");
}
}
} else {
lv2_log_error(&ui->logger, "Unknown message type\n");
......@@ -355,7 +421,7 @@ static const void *extension_data(const char *uri) {
}
static const LV2UI_Descriptor descriptor = {
SAMPLER_UI_URI,
EG_SAMPLER_UI_URI,
instantiate,
cleanup,
port_event,
......
......@@ -13,9 +13,17 @@
#include <stdio.h>
#define EG_SAMPLER_URI "http://lv2.incal.net/plugins/hydrumkit"
#define EG_SAMPLER_UI_URI EG_SAMPLER_URI "#ui"
#define EG_SAMPLER__applyDrumkit EG_SAMPLER_URI "#applyDrumkit"
#define EG_SAMPLER__freeDrumkit EG_SAMPLER_URI "#freeDrumkit"
#define EG_SAMPLER__drumkit EG_SAMPLER_URI "#drumkit"
#define EG_SAMPLER__uiState EG_SAMPLER_URI "#UiState"
#define EG_SAMPLER__huLatencyMax EG_SAMPLER_URI "#hu-latency-max"
#define EG_SAMPLER__huLatencyStdDev EG_SAMPLER_URI "#hu-latency-stddev"
#define EG_SAMPLER__huLatencyLaidBack EG_SAMPLER_URI "#hu-latency-laidback"
#define EG_SAMPLER__huLatencyRegain EG_SAMPLER_URI "#hu-latency-regain"
#define EG_SAMPLER__huVelocityStdDev EG_SAMPLER_URI "#hu-velocity-stddev"
typedef struct {
LV2_URID atom_Float;
......@@ -28,12 +36,16 @@ typedef struct {
LV2_URID eg_freeDrumkit;
LV2_URID eg_drumkit;
LV2_URID midi_Event;
LV2_URID param_gain;
LV2_URID patch_Get;
LV2_URID patch_Set;
//LV2_URID patch_accept;
LV2_URID patch_property;
LV2_URID patch_value;
LV2_URID ui_State;
LV2_URID ui_hu_latency_max;
LV2_URID ui_hu_latency_stddev;
LV2_URID ui_hu_latency_laidback;
LV2_URID ui_hu_latency_regain;
LV2_URID ui_hu_velocity_stddev;
} plugin_uris;
static inline void map_sampler_uris(LV2_URID_Map *map, plugin_uris *uris) {
......@@ -47,12 +59,16 @@ static inline void map_sampler_uris(LV2_URID_Map *map, plugin_uris *uris) {
uris->eg_freeDrumkit = map->map(map->handle, EG_SAMPLER__freeDrumkit);
uris->eg_drumkit = map->map(map->handle, EG_SAMPLER__drumkit);
uris->midi_Event = map->map(map->handle, LV2_MIDI__MidiEvent);
uris->param_gain = map->map(map->handle, LV2_PARAMETERS__gain);
uris->patch_Get = map->map(map->handle, LV2_PATCH__Get);
uris->patch_Set = map->map(map->handle, LV2_PATCH__Set);
//uris->patch_accept = map->map(map->handle, LV2_PATCH__accept);
uris->patch_property = map->map(map->handle, LV2_PATCH__property);
uris->patch_value = map->map(map->handle, LV2_PATCH__value);
uris->ui_State = map->map(map->handle, EG_SAMPLER__uiState);
uris->ui_hu_latency_max = map->map(map->handle, EG_SAMPLER__huLatencyMax);
uris->ui_hu_latency_stddev = map->map(map->handle, EG_SAMPLER__huLatencyStdDev);
uris->ui_hu_latency_laidback = map->map(map->handle, EG_SAMPLER__huLatencyLaidBack);
uris->ui_hu_latency_regain = map->map(map->handle, EG_SAMPLER__huLatencyRegain);
uris->ui_hu_velocity_stddev = map->map(map->handle, EG_SAMPLER__huVelocityStdDev);
}
/**
......
/*
* gui/widgets/knob.c - knob
*
* Minor modifications to the original source to add a 'value-changed'
* signal on drag end.
*
* Copyright (C) 2018 Alexandros Theodotou
* Copyright (C) 2010 Paul Davis
*
......@@ -307,7 +310,7 @@ drag_end (GtkGestureDrag *gesture,
/**
* Creates a knob widget with the given options and binds it to the given value.
*/
KnobWidget *
GtkWidget *
knob_widget_new (float * value,
int size,
float zero)
......@@ -344,7 +347,7 @@ knob_widget_new (float * value,
G_CALLBACK (drag_update), self);
g_signal_connect (G_OBJECT(self->drag), "drag-end",
G_CALLBACK (drag_end), self);
return self;
return GTK_WIDGET(self);
}
static void
......
/*
* gui/widgets/knob.h - knob
*
* Minor modifications to the original source to add a 'value-changed'
* signal on drag end.
*
* Copyright (C) 2018 Alexandros Theodotou
*
* This file is part of Zrythm
......@@ -62,7 +65,7 @@ typedef struct KnobWidgetClass
/**
* Creates a knob widget with the given options and binds it to the given value.
*/
KnobWidget *
GtkWidget *
knob_widget_new (float * value,
int size,
float zero);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment