feat: implement URI-based plugin loading and GUI text input for Carla
Co-authored-by: aider (deepseek/deepseek-coder) <aider@aider.chat>
This commit is contained in:
84
carla.c
84
carla.c
@@ -81,10 +81,88 @@ static int add_gain_plugin(CarlaHost *host, int channel) {
|
|||||||
int carla_add_plugin(CarlaHost *host, int channel, const char *uri, PluginType type) {
|
int carla_add_plugin(CarlaHost *host, int channel, const char *uri, PluginType type) {
|
||||||
if (!host || !host->initialized) return -1;
|
if (!host || !host->initialized) return -1;
|
||||||
if (channel < 0 || channel >= 8) return -1;
|
if (channel < 0 || channel >= 8) return -1;
|
||||||
|
if (!uri) return -1;
|
||||||
|
|
||||||
(void)uri;
|
ChannelRack *rack = &host->channel_racks[channel];
|
||||||
(void)type;
|
if (rack->num_plugins >= 16) return -1;
|
||||||
return add_gain_plugin(host, channel);
|
|
||||||
|
PluginInfo *plugin = &rack->plugins[rack->num_plugins];
|
||||||
|
|
||||||
|
// Parse URI to determine plugin type and name
|
||||||
|
if (strstr(uri, "internal://") == uri) {
|
||||||
|
// Internal plugin
|
||||||
|
plugin->type = PLUGIN_TYPE_INTERNAL;
|
||||||
|
strncpy(plugin->uri, uri, sizeof(plugin->uri) - 1);
|
||||||
|
plugin->uri[sizeof(plugin->uri) - 1] = '\0';
|
||||||
|
|
||||||
|
const char *name = uri + strlen("internal://");
|
||||||
|
if (strcmp(name, "gain") == 0) {
|
||||||
|
strcpy(plugin->name, "Gain");
|
||||||
|
plugin->num_parameters = 1;
|
||||||
|
plugin->parameters = malloc(sizeof(float));
|
||||||
|
plugin->parameters[0] = 1.0f;
|
||||||
|
plugin->parameter_names = malloc(sizeof(char*));
|
||||||
|
plugin->parameter_names[0] = strdup("Gain");
|
||||||
|
} else if (strcmp(name, "reverb") == 0) {
|
||||||
|
strcpy(plugin->name, "Reverb");
|
||||||
|
plugin->num_parameters = 2;
|
||||||
|
plugin->parameters = malloc(2 * sizeof(float));
|
||||||
|
plugin->parameters[0] = 0.5f; // Mix
|
||||||
|
plugin->parameters[1] = 0.5f; // Decay
|
||||||
|
plugin->parameter_names = malloc(2 * sizeof(char*));
|
||||||
|
plugin->parameter_names[0] = strdup("Mix");
|
||||||
|
plugin->parameter_names[1] = strdup("Decay");
|
||||||
|
} else if (strcmp(name, "delay") == 0) {
|
||||||
|
strcpy(plugin->name, "Delay");
|
||||||
|
plugin->num_parameters = 2;
|
||||||
|
plugin->parameters = malloc(2 * sizeof(float));
|
||||||
|
plugin->parameters[0] = 0.3f; // Feedback
|
||||||
|
plugin->parameters[1] = 0.5f; // Mix
|
||||||
|
plugin->parameter_names = malloc(2 * sizeof(char*));
|
||||||
|
plugin->parameter_names[0] = strdup("Feedback");
|
||||||
|
plugin->parameter_names[1] = strdup("Mix");
|
||||||
|
} else if (strcmp(name, "filter") == 0) {
|
||||||
|
strcpy(plugin->name, "Filter");
|
||||||
|
plugin->num_parameters = 2;
|
||||||
|
plugin->parameters = malloc(2 * sizeof(float));
|
||||||
|
plugin->parameters[0] = 1000.0f; // Cutoff
|
||||||
|
plugin->parameters[1] = 1.0f; // Resonance
|
||||||
|
plugin->parameter_names = malloc(2 * sizeof(char*));
|
||||||
|
plugin->parameter_names[0] = strdup("Cutoff");
|
||||||
|
plugin->parameter_names[1] = strdup("Resonance");
|
||||||
|
} else {
|
||||||
|
// Unknown internal plugin, default to gain
|
||||||
|
strcpy(plugin->name, "Unknown Internal");
|
||||||
|
plugin->num_parameters = 0;
|
||||||
|
plugin->parameters = NULL;
|
||||||
|
plugin->parameter_names = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// External plugin (LV2, VST, etc.) - store URI for future Carla integration
|
||||||
|
plugin->type = type;
|
||||||
|
strncpy(plugin->uri, uri, sizeof(plugin->uri) - 1);
|
||||||
|
plugin->uri[sizeof(plugin->uri) - 1] = '\0';
|
||||||
|
|
||||||
|
// Extract a display name from the URI
|
||||||
|
const char *last_slash = strrchr(uri, '/');
|
||||||
|
if (last_slash) {
|
||||||
|
strncpy(plugin->name, last_slash + 1, sizeof(plugin->name) - 1);
|
||||||
|
} else {
|
||||||
|
strncpy(plugin->name, uri, sizeof(plugin->name) - 1);
|
||||||
|
}
|
||||||
|
plugin->name[sizeof(plugin->name) - 1] = '\0';
|
||||||
|
|
||||||
|
plugin->num_parameters = 0;
|
||||||
|
plugin->parameters = NULL;
|
||||||
|
plugin->parameter_names = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin->carla_plugin_id = -1;
|
||||||
|
rack->num_plugins++;
|
||||||
|
|
||||||
|
printf("Added plugin '%s' (URI: %s) to channel %d\n", plugin->name, plugin->uri, channel);
|
||||||
|
|
||||||
|
return rack->num_plugins - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int carla_remove_plugin(CarlaHost *host, int channel, int plugin_index) {
|
int carla_remove_plugin(CarlaHost *host, int channel, int plugin_index) {
|
||||||
|
|||||||
48
gui.c
48
gui.c
@@ -9,6 +9,7 @@
|
|||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "dispatcher.h"
|
#include "dispatcher.h"
|
||||||
|
#include "carla.h"
|
||||||
|
|
||||||
/* microui includes */
|
/* microui includes */
|
||||||
#define MU_IMPLEMENTATION
|
#define MU_IMPLEMENTATION
|
||||||
@@ -44,6 +45,12 @@ static float bpm = 120.0f;
|
|||||||
static int loop_length = 8; /* beats */
|
static int loop_length = 8; /* beats */
|
||||||
static int current_beat = 0;
|
static int current_beat = 0;
|
||||||
|
|
||||||
|
/* Carla host and plugin URI input */
|
||||||
|
static CarlaHost carla_host;
|
||||||
|
static char plugin_uri_input[256];
|
||||||
|
static int plugin_uri_input_len = 0;
|
||||||
|
static int selected_channel = 0;
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------
|
||||||
* drawing helpers (stubs for microui)
|
* drawing helpers (stubs for microui)
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
@@ -114,6 +121,27 @@ static void gui_update(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Plugin URI input */
|
||||||
|
mu_layout_row(ctx, 2, (int[]) { 60, -1 }, 0);
|
||||||
|
mu_label(ctx, "URI:");
|
||||||
|
{
|
||||||
|
char display[256];
|
||||||
|
if (plugin_uri_input_len > 0) {
|
||||||
|
snprintf(display, sizeof(display), "%s_", plugin_uri_input);
|
||||||
|
} else {
|
||||||
|
snprintf(display, sizeof(display), "type URI here...");
|
||||||
|
}
|
||||||
|
mu_label(ctx, display);
|
||||||
|
}
|
||||||
|
mu_layout_row(ctx, 1, (int[]) { -1 }, 0);
|
||||||
|
if (mu_button(ctx, "Add Plugin")) {
|
||||||
|
if (plugin_uri_input_len > 0) {
|
||||||
|
carla_add_plugin(&carla_host, selected_channel, plugin_uri_input, PLUGIN_TYPE_INTERNAL);
|
||||||
|
plugin_uri_input_len = 0;
|
||||||
|
plugin_uri_input[0] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mu_end_window(ctx);
|
mu_end_window(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,6 +155,9 @@ int gui_main(Engine *engine)
|
|||||||
{
|
{
|
||||||
g_engine = engine;
|
g_engine = engine;
|
||||||
|
|
||||||
|
/* Initialize Carla host */
|
||||||
|
carla_init(&carla_host, engine->client);
|
||||||
|
|
||||||
/* initialise microui */
|
/* initialise microui */
|
||||||
ctx = malloc(sizeof(mu_Context));
|
ctx = malloc(sizeof(mu_Context));
|
||||||
if (!ctx) return -1;
|
if (!ctx) return -1;
|
||||||
@@ -148,6 +179,22 @@ int gui_main(Engine *engine)
|
|||||||
/* handle input */
|
/* handle input */
|
||||||
int ch = getch();
|
int ch = getch();
|
||||||
if (ch != ERR) {
|
if (ch != ERR) {
|
||||||
|
/* Handle text input for plugin URI */
|
||||||
|
if (ch >= 32 && ch <= 126 && plugin_uri_input_len < 255) {
|
||||||
|
plugin_uri_input[plugin_uri_input_len++] = (char)ch;
|
||||||
|
plugin_uri_input[plugin_uri_input_len] = '\0';
|
||||||
|
} else if (ch == 127 || ch == KEY_BACKSPACE) {
|
||||||
|
if (plugin_uri_input_len > 0) {
|
||||||
|
plugin_uri_input[--plugin_uri_input_len] = '\0';
|
||||||
|
}
|
||||||
|
} else if (ch == '\n' || ch == '\r') {
|
||||||
|
/* Submit plugin URI */
|
||||||
|
if (plugin_uri_input_len > 0) {
|
||||||
|
carla_add_plugin(&carla_host, selected_channel, plugin_uri_input, PLUGIN_TYPE_INTERNAL);
|
||||||
|
plugin_uri_input_len = 0;
|
||||||
|
plugin_uri_input[0] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'q':
|
case 'q':
|
||||||
case 'Q':
|
case 'Q':
|
||||||
@@ -212,6 +259,7 @@ int gui_main(Engine *engine)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
|
carla_cleanup(&carla_host);
|
||||||
endwin();
|
endwin();
|
||||||
free(ctx);
|
free(ctx);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user