Switch to using atoms to pass paths from ui to core for kit loading
This commit is contained in:
parent
990caaf510
commit
20e94c55fb
73
drmr.c
73
drmr.c
@ -22,35 +22,39 @@
|
||||
#include "drmr.h"
|
||||
#include "drmr_hydrogen.h"
|
||||
|
||||
#define REQ_BUF_SIZE 10
|
||||
|
||||
static void* load_thread(void* arg) {
|
||||
DrMr* drmr = (DrMr*)arg;
|
||||
drmr_sample *loaded_samples,*old_samples;
|
||||
int loaded_count, old_scount;
|
||||
char *request;
|
||||
for(;;) {
|
||||
pthread_mutex_lock(&drmr->load_mutex);
|
||||
pthread_cond_wait(&drmr->load_cond,
|
||||
&drmr->load_mutex);
|
||||
pthread_mutex_unlock(&drmr->load_mutex);
|
||||
int request = (int)floorf(*(drmr->kitReq));
|
||||
if (request == drmr->curKit) continue;
|
||||
old_samples = drmr->samples;
|
||||
old_scount = drmr->num_samples;
|
||||
if (request < 0 || request >= drmr->kits->num_kits) {
|
||||
request = drmr->request_buf[drmr->curReq];
|
||||
loaded_samples = load_hydrogen_kit(request,drmr->rate,&loaded_count);
|
||||
if (!loaded_samples) {
|
||||
fprintf(stderr,"Failed to load kit at: %s\n",request);
|
||||
pthread_mutex_lock(&drmr->load_mutex);
|
||||
drmr->num_samples = 0;
|
||||
drmr->samples = NULL;
|
||||
pthread_mutex_unlock(&drmr->load_mutex);
|
||||
} else {
|
||||
printf("loading kit: %i\n",request);
|
||||
loaded_samples = load_hydrogen_kit(drmr->kits->kits[request].path,drmr->rate,&loaded_count);
|
||||
}
|
||||
else {
|
||||
// just lock for the critical moment when we swap in the new kit
|
||||
printf("loaded kit at: %s\n",request);
|
||||
pthread_mutex_lock(&drmr->load_mutex);
|
||||
drmr->samples = loaded_samples;
|
||||
drmr->num_samples = loaded_count;
|
||||
pthread_mutex_unlock(&drmr->load_mutex);
|
||||
}
|
||||
if (old_scount > 0) free_samples(old_samples,old_scount);
|
||||
drmr->curKit = request;
|
||||
drmr->current_path = request;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -65,7 +69,8 @@ instantiate(const LV2_Descriptor* descriptor,
|
||||
drmr->map = NULL;
|
||||
drmr->samples = NULL;
|
||||
drmr->num_samples = 0;
|
||||
drmr->curKit = -1;
|
||||
drmr->current_path = NULL;
|
||||
drmr->curReq = -1;
|
||||
drmr->rate = rate;
|
||||
|
||||
if (pthread_mutex_init(&drmr->load_mutex, 0)) {
|
||||
@ -79,21 +84,17 @@ instantiate(const LV2_Descriptor* descriptor,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Map midi uri
|
||||
while(*features) {
|
||||
if (!strcmp((*features)->URI, LV2_URID_URI "#map")) {
|
||||
if (!strcmp((*features)->URI, LV2_URID_URI "#map"))
|
||||
drmr->map = (LV2_URID_Map *)((*features)->data);
|
||||
drmr->uris.midi_event =
|
||||
drmr->map->map(drmr->map->handle,
|
||||
"http://lv2plug.in/ns/ext/midi#MidiEvent");
|
||||
}
|
||||
features++;
|
||||
}
|
||||
if (!drmr->map) {
|
||||
fprintf(stderr, "LV2 host does not support urid#map.\n");
|
||||
free(drmr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
map_drmr_uris(drmr->map,&(drmr->uris));
|
||||
|
||||
drmr->kits = scan_kits();
|
||||
if (!drmr->kits) {
|
||||
@ -108,6 +109,9 @@ instantiate(const LV2_Descriptor* descriptor,
|
||||
return 0;
|
||||
}
|
||||
|
||||
drmr->request_buf = malloc(REQ_BUF_SIZE*sizeof(char*));
|
||||
memset(drmr->request_buf,0,REQ_BUF_SIZE*sizeof(char*));
|
||||
|
||||
drmr->gains = malloc(32*sizeof(float*));
|
||||
drmr->pans = malloc(32*sizeof(float*));
|
||||
for(i = 0;i<32;i++) {
|
||||
@ -128,6 +132,9 @@ connect_port(LV2_Handle instance,
|
||||
case DRMR_CONTROL:
|
||||
drmr->control_port = (LV2_Atom_Sequence*)data;
|
||||
break;
|
||||
case DRMR_KITPATH:
|
||||
drmr->kitpath_port = (LV2_Atom_Sequence*)data;
|
||||
break;
|
||||
case DRMR_LEFT:
|
||||
drmr->left = (float*)data;
|
||||
break;
|
||||
@ -135,7 +142,7 @@ connect_port(LV2_Handle instance,
|
||||
drmr->right = (float*)data;
|
||||
break;
|
||||
case DRMR_KITNUM:
|
||||
if(data) drmr->kitReq = (float*)data;
|
||||
//if(data) drmr->kitReq = (float*)data;
|
||||
break;
|
||||
case DRMR_BASENOTE:
|
||||
if (data) drmr->baseNote = (float*)data;
|
||||
@ -182,13 +189,10 @@ static inline void layer_to_sample(drmr_sample *sample, float gain) {
|
||||
#define DB_CO(g) ((g) > GAIN_MIN ? powf(10.0f, (g) * 0.05f) : 0.0f)
|
||||
|
||||
static void run(LV2_Handle instance, uint32_t n_samples) {
|
||||
int i,kitInt,baseNote;
|
||||
int i,baseNote;
|
||||
DrMr* drmr = (DrMr*)instance;
|
||||
|
||||
kitInt = (int)floorf(*(drmr->kitReq));
|
||||
baseNote = (int)floorf(*(drmr->baseNote));
|
||||
if (kitInt != drmr->curKit) // requested a new kit
|
||||
pthread_cond_signal(&drmr->load_cond);
|
||||
|
||||
LV2_SEQUENCE_FOREACH(drmr->control_port, i) {
|
||||
LV2_Atom_Event* const ev = lv2_sequence_iter_get(i);
|
||||
@ -220,9 +224,36 @@ static void run(LV2_Handle instance, uint32_t n_samples) {
|
||||
default:
|
||||
printf("Unhandeled status: %i\n",(*data)>>4);
|
||||
}
|
||||
} else printf("unrecognized event\n");
|
||||
}
|
||||
else if (ev->body.type == drmr->uris.atom_resource) {
|
||||
const LV2_Atom_Object *obj = (LV2_Atom_Object*)&ev->body;
|
||||
if (obj->body.otype == drmr->uris.ui_msg) {
|
||||
const LV2_Atom* path = NULL;
|
||||
lv2_object_get(obj, drmr->uris.kit_path, &path, 0);
|
||||
if (!path)
|
||||
fprintf(stderr,"Got UI message without kit_path, ignoring\n");
|
||||
else {
|
||||
int reqPos = (drmr->curReq+1)%REQ_BUF_SIZE;
|
||||
char *tmp = NULL;
|
||||
if (reqPos >= 0 &&
|
||||
drmr->request_buf[reqPos])
|
||||
tmp = drmr->request_buf[reqPos];
|
||||
drmr->request_buf[reqPos] = strdup(LV2_ATOM_BODY(path));
|
||||
drmr->curReq = reqPos;
|
||||
if (tmp) free(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else printf("unrecognized event\n");
|
||||
}
|
||||
|
||||
if ((drmr->curReq >= 0) &&
|
||||
drmr->request_buf[drmr->curReq] &&
|
||||
(!drmr->current_path ||
|
||||
strcmp(drmr->current_path,
|
||||
drmr->request_buf[drmr->curReq])))
|
||||
pthread_cond_signal(&drmr->load_cond);
|
||||
|
||||
for(i = 0;i<n_samples;i++) {
|
||||
drmr->left[i] = 0.0f;
|
||||
drmr->right[i] = 0.0f;
|
||||
|
37
drmr.h
37
drmr.h
@ -137,31 +137,40 @@ typedef enum {
|
||||
DRMR_PAN_THIRTY,
|
||||
DRMR_PAN_THIRTYONE,
|
||||
DRMR_PAN_THIRTYTWO,
|
||||
DRMR_KITPATH,
|
||||
DRMR_NUM_PORTS
|
||||
} DrMrPortIndex;
|
||||
|
||||
typedef struct {
|
||||
LV2_URID midi_event;
|
||||
LV2_URID ui_msg;
|
||||
LV2_URID kit_path;
|
||||
LV2_URID atom_eventTransfer;
|
||||
LV2_URID atom_resource;
|
||||
} drmr_uris;
|
||||
|
||||
typedef struct {
|
||||
// Ports
|
||||
float* left;
|
||||
float* right;
|
||||
LV2_Atom_Sequence *control_port;
|
||||
LV2_Atom_Sequence *kitpath_port;
|
||||
|
||||
// params
|
||||
float** gains;
|
||||
float** pans;
|
||||
float* kitReq;
|
||||
float* baseNote;
|
||||
double rate;
|
||||
|
||||
// URIs
|
||||
LV2_URID_Map* map;
|
||||
struct {
|
||||
LV2_URID midi_event;
|
||||
} uris;
|
||||
drmr_uris uris;
|
||||
|
||||
// Available kits
|
||||
kits* kits;
|
||||
int curKit;
|
||||
char* current_path;
|
||||
char** request_buf;
|
||||
int curReq;
|
||||
|
||||
// Samples
|
||||
drmr_sample* samples;
|
||||
@ -174,5 +183,23 @@ typedef struct {
|
||||
|
||||
} DrMr;
|
||||
|
||||
static inline
|
||||
void map_drmr_uris(LV2_URID_Map *map,
|
||||
drmr_uris *uris) {
|
||||
uris->midi_event =
|
||||
map->map(map->handle,
|
||||
"http://lv2plug.in/ns/ext/midi#MidiEvent");
|
||||
uris->ui_msg =
|
||||
map->map(map->handle,
|
||||
DRMR_URI "#uimsg");
|
||||
uris->kit_path =
|
||||
map->map(map->handle,
|
||||
DRMR_URI "#kitpath");
|
||||
uris->atom_eventTransfer =
|
||||
map->map(map->handle, LV2_ATOM__eventTransfer);
|
||||
uris->atom_resource =
|
||||
map->map(map->handle, LV2_ATOM__Resource);
|
||||
}
|
||||
|
||||
|
||||
#endif // DRMR_H
|
||||
|
65
drmr_ui.c
65
drmr_ui.c
@ -21,6 +21,11 @@
|
||||
#include "drmr.h"
|
||||
#include "drmr_hydrogen.h"
|
||||
#include "nknob.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"
|
||||
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
|
||||
#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
|
||||
|
||||
#define DRMR_UI_URI "http://github.com/nicklan/drmr#ui"
|
||||
@ -28,6 +33,10 @@
|
||||
typedef struct {
|
||||
LV2UI_Write_Function write;
|
||||
LV2UI_Controller controller;
|
||||
LV2_Atom_Forge forge;
|
||||
|
||||
LV2_URID_Map *map;
|
||||
drmr_uris uris;
|
||||
|
||||
GtkWidget *drmr_widget;
|
||||
GtkTable *sample_table;
|
||||
@ -271,12 +280,30 @@ static gboolean kit_callback(gpointer data) {
|
||||
return FALSE; // don't keep calling
|
||||
}
|
||||
|
||||
static LV2_Atom* build_path_message(DrMrUi *ui, const char* path) {
|
||||
LV2_Atom_Forge_Frame set_frame;
|
||||
LV2_Atom* msg = (LV2_Atom*)lv2_atom_forge_resource
|
||||
(&ui->forge, &set_frame, 1, ui->uris.ui_msg);
|
||||
lv2_atom_forge_property_head(&ui->forge, ui->uris.kit_path,0);
|
||||
lv2_atom_forge_path(&ui->forge, path, strlen(path));
|
||||
lv2_atom_forge_pop(&ui->forge,&set_frame);
|
||||
return msg;
|
||||
}
|
||||
|
||||
static void kit_combobox_changed(GtkComboBox* box, gpointer data) {
|
||||
DrMrUi* ui = (DrMrUi*)data;
|
||||
gint new_kit = gtk_combo_box_get_active (GTK_COMBO_BOX(box));
|
||||
float fkit = (float)new_kit;
|
||||
if (ui->curKit != new_kit)
|
||||
ui->write(ui->controller,DRMR_KITNUM,4,0,&fkit);
|
||||
|
||||
if (ui->curKit != new_kit) {
|
||||
uint8_t msg_buf[1024];
|
||||
lv2_atom_forge_set_buffer(&ui->forge, msg_buf, 1024);
|
||||
LV2_Atom *msg = build_path_message(ui,ui->kits->kits[new_kit].path);
|
||||
|
||||
ui->write(ui->controller,DRMR_CONTROL,
|
||||
lv2_atom_total_size(msg),
|
||||
ui->uris.atom_eventTransfer,
|
||||
msg);
|
||||
}
|
||||
|
||||
/* Call our update func after 100 milliseconds.
|
||||
*
|
||||
@ -424,11 +451,27 @@ instantiate(const LV2UI_Descriptor* descriptor,
|
||||
ui->write = write_function;
|
||||
ui->controller = controller;
|
||||
ui->drmr_widget = NULL;
|
||||
ui->map = NULL;
|
||||
ui->curKit = -1;
|
||||
ui->samples = 0;
|
||||
ui->bundle_path = g_strdup(bundle_path);
|
||||
*widget = NULL;
|
||||
|
||||
while(*features) {
|
||||
if (!strcmp((*features)->URI, LV2_URID_URI "#map"))
|
||||
ui->map = (LV2_URID_Map *)((*features)->data);
|
||||
features++;
|
||||
}
|
||||
if (!ui->map) {
|
||||
fprintf(stderr, "LV2 host does not support urid#map.\n");
|
||||
free(ui);
|
||||
return 0;
|
||||
}
|
||||
map_drmr_uris(ui->map,&(ui->uris));
|
||||
|
||||
ui->bundle_path = g_strdup(bundle_path);
|
||||
|
||||
lv2_atom_forge_init(&ui->forge,ui->map);
|
||||
|
||||
build_drmr_ui(ui);
|
||||
|
||||
ui->kits = scan_kits();
|
||||
@ -493,19 +536,7 @@ port_event(LV2UI_Handle handle,
|
||||
DrMrPortIndex index = (DrMrPortIndex)port_index;
|
||||
DrMrUi* ui = (DrMrUi*)handle;
|
||||
|
||||
if (index == DRMR_KITNUM) {
|
||||
if (format != 0)
|
||||
fprintf(stderr,"Invalid format for kitnum: %i\n",format);
|
||||
else {
|
||||
int kit = (int)(*((float*)buffer));
|
||||
ui->kitReq = kit;
|
||||
if (!idle) {
|
||||
idle = TRUE;
|
||||
g_idle_add(kit_callback,ui);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (index == DRMR_BASENOTE) {
|
||||
if (index == DRMR_BASENOTE) {
|
||||
int base = (int)(*((float*)buffer));
|
||||
if (base >= 21 && base <= 107) {
|
||||
setBaseLabel((int)base);
|
||||
|
Loading…
Reference in New Issue
Block a user