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.h"
|
||||||
#include "drmr_hydrogen.h"
|
#include "drmr_hydrogen.h"
|
||||||
|
|
||||||
|
#define REQ_BUF_SIZE 10
|
||||||
|
|
||||||
static void* load_thread(void* arg) {
|
static void* load_thread(void* arg) {
|
||||||
DrMr* drmr = (DrMr*)arg;
|
DrMr* drmr = (DrMr*)arg;
|
||||||
drmr_sample *loaded_samples,*old_samples;
|
drmr_sample *loaded_samples,*old_samples;
|
||||||
int loaded_count, old_scount;
|
int loaded_count, old_scount;
|
||||||
|
char *request;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
pthread_mutex_lock(&drmr->load_mutex);
|
pthread_mutex_lock(&drmr->load_mutex);
|
||||||
pthread_cond_wait(&drmr->load_cond,
|
pthread_cond_wait(&drmr->load_cond,
|
||||||
&drmr->load_mutex);
|
&drmr->load_mutex);
|
||||||
pthread_mutex_unlock(&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_samples = drmr->samples;
|
||||||
old_scount = drmr->num_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);
|
pthread_mutex_lock(&drmr->load_mutex);
|
||||||
drmr->num_samples = 0;
|
drmr->num_samples = 0;
|
||||||
drmr->samples = NULL;
|
drmr->samples = NULL;
|
||||||
pthread_mutex_unlock(&drmr->load_mutex);
|
pthread_mutex_unlock(&drmr->load_mutex);
|
||||||
} else {
|
}
|
||||||
printf("loading kit: %i\n",request);
|
else {
|
||||||
loaded_samples = load_hydrogen_kit(drmr->kits->kits[request].path,drmr->rate,&loaded_count);
|
|
||||||
// just lock for the critical moment when we swap in the new kit
|
// 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);
|
pthread_mutex_lock(&drmr->load_mutex);
|
||||||
drmr->samples = loaded_samples;
|
drmr->samples = loaded_samples;
|
||||||
drmr->num_samples = loaded_count;
|
drmr->num_samples = loaded_count;
|
||||||
pthread_mutex_unlock(&drmr->load_mutex);
|
pthread_mutex_unlock(&drmr->load_mutex);
|
||||||
}
|
}
|
||||||
if (old_scount > 0) free_samples(old_samples,old_scount);
|
if (old_scount > 0) free_samples(old_samples,old_scount);
|
||||||
drmr->curKit = request;
|
drmr->current_path = request;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -65,7 +69,8 @@ instantiate(const LV2_Descriptor* descriptor,
|
|||||||
drmr->map = NULL;
|
drmr->map = NULL;
|
||||||
drmr->samples = NULL;
|
drmr->samples = NULL;
|
||||||
drmr->num_samples = 0;
|
drmr->num_samples = 0;
|
||||||
drmr->curKit = -1;
|
drmr->current_path = NULL;
|
||||||
|
drmr->curReq = -1;
|
||||||
drmr->rate = rate;
|
drmr->rate = rate;
|
||||||
|
|
||||||
if (pthread_mutex_init(&drmr->load_mutex, 0)) {
|
if (pthread_mutex_init(&drmr->load_mutex, 0)) {
|
||||||
@ -79,21 +84,17 @@ instantiate(const LV2_Descriptor* descriptor,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map midi uri
|
|
||||||
while(*features) {
|
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->map = (LV2_URID_Map *)((*features)->data);
|
||||||
drmr->uris.midi_event =
|
|
||||||
drmr->map->map(drmr->map->handle,
|
|
||||||
"http://lv2plug.in/ns/ext/midi#MidiEvent");
|
|
||||||
}
|
|
||||||
features++;
|
features++;
|
||||||
}
|
}
|
||||||
if (!drmr->map) {
|
if (!drmr->map) {
|
||||||
fprintf(stderr, "LV2 host does not support urid#map.\n");
|
fprintf(stderr, "LV2 host does not support urid#map.\n");
|
||||||
free(drmr);
|
free(drmr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
map_drmr_uris(drmr->map,&(drmr->uris));
|
||||||
|
|
||||||
drmr->kits = scan_kits();
|
drmr->kits = scan_kits();
|
||||||
if (!drmr->kits) {
|
if (!drmr->kits) {
|
||||||
@ -108,6 +109,9 @@ instantiate(const LV2_Descriptor* descriptor,
|
|||||||
return 0;
|
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->gains = malloc(32*sizeof(float*));
|
||||||
drmr->pans = malloc(32*sizeof(float*));
|
drmr->pans = malloc(32*sizeof(float*));
|
||||||
for(i = 0;i<32;i++) {
|
for(i = 0;i<32;i++) {
|
||||||
@ -128,6 +132,9 @@ connect_port(LV2_Handle instance,
|
|||||||
case DRMR_CONTROL:
|
case DRMR_CONTROL:
|
||||||
drmr->control_port = (LV2_Atom_Sequence*)data;
|
drmr->control_port = (LV2_Atom_Sequence*)data;
|
||||||
break;
|
break;
|
||||||
|
case DRMR_KITPATH:
|
||||||
|
drmr->kitpath_port = (LV2_Atom_Sequence*)data;
|
||||||
|
break;
|
||||||
case DRMR_LEFT:
|
case DRMR_LEFT:
|
||||||
drmr->left = (float*)data;
|
drmr->left = (float*)data;
|
||||||
break;
|
break;
|
||||||
@ -135,7 +142,7 @@ connect_port(LV2_Handle instance,
|
|||||||
drmr->right = (float*)data;
|
drmr->right = (float*)data;
|
||||||
break;
|
break;
|
||||||
case DRMR_KITNUM:
|
case DRMR_KITNUM:
|
||||||
if(data) drmr->kitReq = (float*)data;
|
//if(data) drmr->kitReq = (float*)data;
|
||||||
break;
|
break;
|
||||||
case DRMR_BASENOTE:
|
case DRMR_BASENOTE:
|
||||||
if (data) drmr->baseNote = (float*)data;
|
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)
|
#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) {
|
static void run(LV2_Handle instance, uint32_t n_samples) {
|
||||||
int i,kitInt,baseNote;
|
int i,baseNote;
|
||||||
DrMr* drmr = (DrMr*)instance;
|
DrMr* drmr = (DrMr*)instance;
|
||||||
|
|
||||||
kitInt = (int)floorf(*(drmr->kitReq));
|
|
||||||
baseNote = (int)floorf(*(drmr->baseNote));
|
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_SEQUENCE_FOREACH(drmr->control_port, i) {
|
||||||
LV2_Atom_Event* const ev = lv2_sequence_iter_get(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:
|
default:
|
||||||
printf("Unhandeled status: %i\n",(*data)>>4);
|
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++) {
|
for(i = 0;i<n_samples;i++) {
|
||||||
drmr->left[i] = 0.0f;
|
drmr->left[i] = 0.0f;
|
||||||
drmr->right[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_THIRTY,
|
||||||
DRMR_PAN_THIRTYONE,
|
DRMR_PAN_THIRTYONE,
|
||||||
DRMR_PAN_THIRTYTWO,
|
DRMR_PAN_THIRTYTWO,
|
||||||
|
DRMR_KITPATH,
|
||||||
DRMR_NUM_PORTS
|
DRMR_NUM_PORTS
|
||||||
} DrMrPortIndex;
|
} 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 {
|
typedef struct {
|
||||||
// Ports
|
// Ports
|
||||||
float* left;
|
float* left;
|
||||||
float* right;
|
float* right;
|
||||||
LV2_Atom_Sequence *control_port;
|
LV2_Atom_Sequence *control_port;
|
||||||
|
LV2_Atom_Sequence *kitpath_port;
|
||||||
|
|
||||||
// params
|
// params
|
||||||
float** gains;
|
float** gains;
|
||||||
float** pans;
|
float** pans;
|
||||||
float* kitReq;
|
|
||||||
float* baseNote;
|
float* baseNote;
|
||||||
double rate;
|
double rate;
|
||||||
|
|
||||||
// URIs
|
// URIs
|
||||||
LV2_URID_Map* map;
|
LV2_URID_Map* map;
|
||||||
struct {
|
drmr_uris uris;
|
||||||
LV2_URID midi_event;
|
|
||||||
} uris;
|
|
||||||
|
|
||||||
// Available kits
|
// Available kits
|
||||||
kits* kits;
|
kits* kits;
|
||||||
int curKit;
|
char* current_path;
|
||||||
|
char** request_buf;
|
||||||
|
int curReq;
|
||||||
|
|
||||||
// Samples
|
// Samples
|
||||||
drmr_sample* samples;
|
drmr_sample* samples;
|
||||||
@ -174,5 +183,23 @@ typedef struct {
|
|||||||
|
|
||||||
} DrMr;
|
} 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
|
#endif // DRMR_H
|
||||||
|
65
drmr_ui.c
65
drmr_ui.c
@ -21,6 +21,11 @@
|
|||||||
#include "drmr.h"
|
#include "drmr.h"
|
||||||
#include "drmr_hydrogen.h"
|
#include "drmr_hydrogen.h"
|
||||||
#include "nknob.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"
|
#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
|
||||||
|
|
||||||
#define DRMR_UI_URI "http://github.com/nicklan/drmr#ui"
|
#define DRMR_UI_URI "http://github.com/nicklan/drmr#ui"
|
||||||
@ -28,6 +33,10 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
LV2UI_Write_Function write;
|
LV2UI_Write_Function write;
|
||||||
LV2UI_Controller controller;
|
LV2UI_Controller controller;
|
||||||
|
LV2_Atom_Forge forge;
|
||||||
|
|
||||||
|
LV2_URID_Map *map;
|
||||||
|
drmr_uris uris;
|
||||||
|
|
||||||
GtkWidget *drmr_widget;
|
GtkWidget *drmr_widget;
|
||||||
GtkTable *sample_table;
|
GtkTable *sample_table;
|
||||||
@ -271,12 +280,30 @@ static gboolean kit_callback(gpointer data) {
|
|||||||
return FALSE; // don't keep calling
|
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) {
|
static void kit_combobox_changed(GtkComboBox* box, gpointer data) {
|
||||||
DrMrUi* ui = (DrMrUi*)data;
|
DrMrUi* ui = (DrMrUi*)data;
|
||||||
gint new_kit = gtk_combo_box_get_active (GTK_COMBO_BOX(box));
|
gint new_kit = gtk_combo_box_get_active (GTK_COMBO_BOX(box));
|
||||||
float fkit = (float)new_kit;
|
|
||||||
if (ui->curKit != new_kit)
|
if (ui->curKit != new_kit) {
|
||||||
ui->write(ui->controller,DRMR_KITNUM,4,0,&fkit);
|
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.
|
/* Call our update func after 100 milliseconds.
|
||||||
*
|
*
|
||||||
@ -424,11 +451,27 @@ instantiate(const LV2UI_Descriptor* descriptor,
|
|||||||
ui->write = write_function;
|
ui->write = write_function;
|
||||||
ui->controller = controller;
|
ui->controller = controller;
|
||||||
ui->drmr_widget = NULL;
|
ui->drmr_widget = NULL;
|
||||||
|
ui->map = NULL;
|
||||||
ui->curKit = -1;
|
ui->curKit = -1;
|
||||||
ui->samples = 0;
|
ui->samples = 0;
|
||||||
ui->bundle_path = g_strdup(bundle_path);
|
|
||||||
*widget = NULL;
|
*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);
|
build_drmr_ui(ui);
|
||||||
|
|
||||||
ui->kits = scan_kits();
|
ui->kits = scan_kits();
|
||||||
@ -493,19 +536,7 @@ port_event(LV2UI_Handle handle,
|
|||||||
DrMrPortIndex index = (DrMrPortIndex)port_index;
|
DrMrPortIndex index = (DrMrPortIndex)port_index;
|
||||||
DrMrUi* ui = (DrMrUi*)handle;
|
DrMrUi* ui = (DrMrUi*)handle;
|
||||||
|
|
||||||
if (index == DRMR_KITNUM) {
|
if (index == DRMR_BASENOTE) {
|
||||||
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) {
|
|
||||||
int base = (int)(*((float*)buffer));
|
int base = (int)(*((float*)buffer));
|
||||||
if (base >= 21 && base <= 107) {
|
if (base >= 21 && base <= 107) {
|
||||||
setBaseLabel((int)base);
|
setBaseLabel((int)base);
|
||||||
|
Loading…
Reference in New Issue
Block a user