Send notifications of kit load back to the ui

This commit is contained in:
Nick Lanham 2012-03-23 14:19:57 +01:00
parent 20e94c55fb
commit 58ecf566fa
4 changed files with 71 additions and 24 deletions

40
drmr.c
View File

@ -24,6 +24,8 @@
#define REQ_BUF_SIZE 10 #define REQ_BUF_SIZE 10
static int current_kit_changed = 0;
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;
@ -55,6 +57,7 @@ static void* load_thread(void* arg) {
} }
if (old_scount > 0) free_samples(old_samples,old_scount); if (old_scount > 0) free_samples(old_samples,old_scount);
drmr->current_path = request; drmr->current_path = request;
current_kit_changed = 1;
} }
return 0; return 0;
} }
@ -96,12 +99,7 @@ instantiate(const LV2_Descriptor* descriptor,
} }
map_drmr_uris(drmr->map,&(drmr->uris)); map_drmr_uris(drmr->map,&(drmr->uris));
drmr->kits = scan_kits(); lv2_atom_forge_init(&drmr->forge, drmr->map);
if (!drmr->kits) {
fprintf(stderr, "No drum kits found\n");
free(drmr);
return 0;
}
if (pthread_create(&drmr->load_thread, 0, load_thread, drmr)) { if (pthread_create(&drmr->load_thread, 0, load_thread, drmr)) {
fprintf(stderr, "Could not initialize loading thread.\n"); fprintf(stderr, "Could not initialize loading thread.\n");
@ -132,8 +130,8 @@ 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: case DRMR_CORE_EVENT:
drmr->kitpath_port = (LV2_Atom_Sequence*)data; drmr->core_event_port = (LV2_Atom_Sequence*)data;
break; break;
case DRMR_LEFT: case DRMR_LEFT:
drmr->left = (float*)data; drmr->left = (float*)data;
@ -161,6 +159,16 @@ connect_port(LV2_Handle instance,
} }
} }
static inline LV2_Atom* build_update_message(DrMr *drmr, const char* kit) {
LV2_Atom_Forge_Frame set_frame;
LV2_Atom* msg = (LV2_Atom*)lv2_atom_forge_resource
(&drmr->forge, &set_frame, 1, drmr->uris.ui_msg);
lv2_atom_forge_property_head(&drmr->forge, drmr->uris.kit_path,0);
lv2_atom_forge_string(&drmr->forge, kit, strlen(kit));
lv2_atom_forge_pop(&drmr->forge,&set_frame);
return msg;
}
static inline void layer_to_sample(drmr_sample *sample, float gain) { static inline void layer_to_sample(drmr_sample *sample, float gain) {
int i; int i;
float mapped_gain = (1-(gain/GAIN_MIN)); float mapped_gain = (1-(gain/GAIN_MIN));
@ -194,6 +202,13 @@ static void run(LV2_Handle instance, uint32_t n_samples) {
baseNote = (int)floorf(*(drmr->baseNote)); baseNote = (int)floorf(*(drmr->baseNote));
const uint32_t event_capacity = drmr->core_event_port->atom.size;
lv2_atom_forge_set_buffer(&drmr->forge,
(uint8_t*)drmr->core_event_port,
event_capacity);
LV2_Atom_Forge_Frame seq_frame;
lv2_atom_forge_sequence_head(&drmr->forge, &seq_frame, 0);
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);
if (ev->body.type == drmr->uris.midi_event) { if (ev->body.type == drmr->uris.midi_event) {
@ -254,6 +269,14 @@ static void run(LV2_Handle instance, uint32_t n_samples) {
drmr->request_buf[drmr->curReq]))) drmr->request_buf[drmr->curReq])))
pthread_cond_signal(&drmr->load_cond); pthread_cond_signal(&drmr->load_cond);
if (current_kit_changed) {
current_kit_changed = 0;
lv2_atom_forge_frame_time(&drmr->forge, 0);
build_update_message(drmr,drmr->current_path);
}
lv2_atom_forge_pop(&drmr->forge, &seq_frame);
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;
@ -303,7 +326,6 @@ static void cleanup(LV2_Handle instance) {
pthread_join(drmr->load_thread, 0); pthread_join(drmr->load_thread, 0);
if (drmr->num_samples > 0) if (drmr->num_samples > 0)
free_samples(drmr->samples,drmr->num_samples); free_samples(drmr->samples,drmr->num_samples);
free_kits(drmr->kits);
free(drmr->gains); free(drmr->gains);
free(instance); free(instance);
} }

9
drmr.h
View File

@ -137,7 +137,7 @@ typedef enum {
DRMR_PAN_THIRTY, DRMR_PAN_THIRTY,
DRMR_PAN_THIRTYONE, DRMR_PAN_THIRTYONE,
DRMR_PAN_THIRTYTWO, DRMR_PAN_THIRTYTWO,
DRMR_KITPATH, DRMR_CORE_EVENT,
DRMR_NUM_PORTS DRMR_NUM_PORTS
} DrMrPortIndex; } DrMrPortIndex;
@ -154,7 +154,9 @@ typedef struct {
float* left; float* left;
float* right; float* right;
LV2_Atom_Sequence *control_port; LV2_Atom_Sequence *control_port;
LV2_Atom_Sequence *kitpath_port; LV2_Atom_Sequence *core_event_port;
LV2_Atom_Forge forge;
// params // params
float** gains; float** gains;
@ -166,8 +168,7 @@ typedef struct {
LV2_URID_Map* map; LV2_URID_Map* map;
drmr_uris uris; drmr_uris uris;
// Available kits // Kit info
kits* kits;
char* current_path; char* current_path;
char** request_buf; char** request_buf;
int curReq; int curReq;

View File

@ -23,11 +23,19 @@
a lv2:InputPort , atom:MessagePort; a lv2:InputPort , atom:MessagePort;
atom:bufferType atom:Sequence ; atom:bufferType atom:Sequence ;
atom:supports <http://lv2plug.in/ns/ext/midi#MidiEvent> , atom:supports <http://lv2plug.in/ns/ext/midi#MidiEvent> ,
<http://lv2plug.in/ns/ext/atom#Path> ; <http://lv2plug.in/ns/ext/atom#Resource> ;
lv2:index 0; lv2:index 0;
lv2:symbol "control"; lv2:symbol "control";
lv2:name "Control"; lv2:name "Control";
], ],
[
a lv2:OutputPort , atom:MessagePort ;
atom:bufferType atom:Sequence ;
atom:supports <http://lv2plug.in/ns/ext/atom#Resource> ;
lv2:index 69 ;
lv2:symbol "core_events" ;
lv2:name "Core Events"
],
[ [
a lv2:AudioPort, lv2:OutputPort; a lv2:AudioPort, lv2:OutputPort;
lv2:index 1; lv2:index 1;

View File

@ -304,15 +304,6 @@ static void kit_combobox_changed(GtkComboBox* box, gpointer data) {
ui->uris.atom_eventTransfer, ui->uris.atom_eventTransfer,
msg); msg);
} }
/* Call our update func after 100 milliseconds.
*
* This is a hack to deal with hosts that don't send
* back port_events properly after the write function.
* In particular, qtractor doesn't, at the moment.
*/
ui->kitReq = new_kit;
g_timeout_add(100,kit_callback,ui);
} }
static void position_combobox_changed(GtkComboBox* box, gpointer data) { static void position_combobox_changed(GtkComboBox* box, gpointer data) {
@ -536,7 +527,32 @@ 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_BASENOTE) { if (index == DRMR_CORE_EVENT) {
if (format == ui->uris.atom_eventTransfer) {
LV2_Atom* atom = (LV2_Atom*)buffer;
if (atom->type == ui->uris.atom_resource) {
LV2_Atom_Object* obj = (LV2_Atom_Object*)atom;
const LV2_Atom* path = NULL;
lv2_object_get(obj, ui->uris.kit_path, &path, 0);
if (!path)
fprintf(stderr,"Got UI message without kit_path, ignoring\n");
else {
char *kitpath = LV2_ATOM_BODY(path);
int i;
for(i = 0;i < ui->kits->num_kits;i++)
if (!strcmp(ui->kits->kits[i].path,kitpath))
break;
if (i < ui->kits->num_kits) {
ui->kitReq = i;
g_idle_add(kit_callback,ui);
}
}
} else
fprintf(stderr, "Unknown message type.\n");
} else
fprintf(stderr, "Unknown format.\n");
}
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);