Allow sample to be triggered by clicking on notification led

This commit is contained in:
Nick Lanham 2012-03-27 16:34:12 +02:00
parent b5f2a60d44
commit 925f6b20a4
3 changed files with 63 additions and 22 deletions

51
drmr.c
View File

@ -212,6 +212,26 @@ static inline void layer_to_sample(drmr_sample *sample, float gain) {
sample->data = sample->layers[0].data;
}
static inline void trigger_sample(DrMr *drmr, int nn, uint8_t* const data) {
// need to mutex this to avoid getting the samples array
// changed after the check that the midi-note is valid
pthread_mutex_lock(&drmr->load_mutex);
if (nn >= 0 && nn < drmr->num_samples) {
if (drmr->samples[nn].layer_count > 0) {
layer_to_sample(drmr->samples+nn,*(drmr->gains[nn]));
if (drmr->samples[nn].limit == 0)
fprintf(stderr,"Failed to find layer at: %i for %f\n",nn,*drmr->gains[nn]);
}
if (data) {
lv2_atom_forge_frame_time(&drmr->forge, 0);
build_midi_info_message(drmr,data);
}
drmr->samples[nn].active = 1;
drmr->samples[nn].offset = 0;
}
pthread_mutex_unlock(&drmr->load_mutex);
}
#define DB3SCALE -0.8317830986718104f
#define DB3SCALEPO 1.8317830986718104f
// taken from lv2 example amp plugin
@ -242,21 +262,7 @@ static void run(LV2_Handle instance, uint32_t n_samples) {
case 9: {
uint8_t nn = data[1];
nn-=baseNote;
// need to mutex this to avoid getting the samples array
// changed after the check that the midi-note is valid
pthread_mutex_lock(&drmr->load_mutex);
if (nn >= 0 && nn < drmr->num_samples) {
if (drmr->samples[nn].layer_count > 0) {
layer_to_sample(drmr->samples+nn,*(drmr->gains[nn]));
if (drmr->samples[nn].limit == 0)
fprintf(stderr,"Failed to find layer at: %i for %f\n",nn,*drmr->gains[nn]);
}
lv2_atom_forge_frame_time(&drmr->forge, 0);
build_midi_info_message(drmr,data);
drmr->samples[nn].active = 1;
drmr->samples[nn].offset = 0;
}
pthread_mutex_unlock(&drmr->load_mutex);
trigger_sample(drmr,nn,data);
break;
}
default:
@ -267,10 +273,9 @@ static void run(LV2_Handle instance, uint32_t n_samples) {
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 {
const LV2_Atom* trigger = NULL;
lv2_object_get(obj, drmr->uris.kit_path, &path, drmr->uris.sample_trigger, &trigger, 0);
if (path) {
int reqPos = (drmr->curReq+1)%REQ_BUF_SIZE;
char *tmp = NULL;
if (reqPos >= 0 &&
@ -280,6 +285,14 @@ static void run(LV2_Handle instance, uint32_t n_samples) {
drmr->curReq = reqPos;
if (tmp) free(tmp);
}
if (trigger) {
int32_t si = ((const LV2_Atom_Int*)trigger)->body;
uint8_t mdata[3];
mdata[0] = 0x90; // note on
mdata[1] = si+baseNote;
mdata[2] = 0x7f;
trigger_sample(drmr,si,mdata);
}
} else if (obj->body.otype == drmr->uris.get_state) {
lv2_atom_forge_frame_time(&drmr->forge, 0);
build_state_message(drmr);

4
drmr.h
View File

@ -150,6 +150,7 @@ typedef struct {
LV2_URID string_urid;
LV2_URID get_state;
LV2_URID midi_info;
LV2_URID sample_trigger;
} drmr_uris;
typedef struct {
@ -208,6 +209,9 @@ void map_drmr_uris(LV2_URID_Map *map,
uris->midi_info =
map->map(map->handle,
DRMR_URI "#midiinfo");
uris->sample_trigger =
map->map(map->handle,
DRMR_URI "#sampletrigger");
uris->atom_eventTransfer =
map->map(map->handle, LV2_ATOM__eventTransfer);
uris->atom_resource =

View File

@ -65,7 +65,7 @@ typedef struct {
int samples;
int baseNote;
GQuark gain_quark, pan_quark;
GQuark gain_quark, pan_quark, trigger_quark;
int curKit;
int kitReq;
@ -92,6 +92,24 @@ static gboolean pan_callback(GtkRange* range, GtkScrollType type, gdouble value,
return FALSE;
}
static gboolean trigger_led_clicked(GtkWidget *widget, GdkEvent *event, gpointer data) {
LV2_Atom_Forge_Frame set_frame;
DrMrUi* ui = (DrMrUi*)data;
int32_t tidx = GPOINTER_TO_INT(g_object_get_qdata(G_OBJECT(widget),ui->trigger_quark));
uint8_t msg_buf[1024];
lv2_atom_forge_set_buffer(&ui->forge, msg_buf, 1024);
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.sample_trigger,0);
lv2_atom_forge_int(&ui->forge, tidx);
lv2_atom_forge_pop(&ui->forge,&set_frame);
ui->write(ui->controller,DRMR_CONTROL,
lv2_atom_total_size(msg),
ui->uris.atom_eventTransfer,
msg);
return FALSE;
}
static void fill_sample_table(DrMrUi* ui, int samples, char** names, GtkWidget** notify_leds, GtkWidget** gain_sliders, GtkWidget** pan_sliders) {
int row = 0;
int col = 0;
@ -116,7 +134,7 @@ static void fill_sample_table(DrMrUi* ui, int samples, char** names, GtkWidget**
for(si = 0;si<samples;si++) {
GtkWidget *frame,*vbox,*hbox,*gain_vbox,*pan_vbox;
GtkWidget *button_box, *led;
GtkWidget *button_box, *led_event_box, *led;
GtkWidget* gain_slider;
GtkWidget* pan_slider;
GtkWidget* gain_label;
@ -188,10 +206,15 @@ static void fill_sample_table(DrMrUi* ui, int samples, char** names, GtkWidget**
button_box = gtk_hbox_new(false,2);
led_event_box = gtk_event_box_new();
g_object_set_qdata(G_OBJECT(led_event_box),ui->trigger_quark,GINT_TO_POINTER(si));
g_signal_connect(G_OBJECT(led_event_box),"button-release-event",
G_CALLBACK(trigger_led_clicked),ui);
led = gtk_image_new_from_pixbuf(led_off_pixbuf);
if (notify_leds) notify_leds[si] = led;
gtk_container_add(GTK_CONTAINER(led_event_box),led);
gtk_box_pack_start(GTK_BOX(button_box),led,false,false,0);
gtk_box_pack_start(GTK_BOX(button_box),led_event_box,false,false,0);
gtk_box_pack_start(GTK_BOX(button_box),gtk_label_new(""),true,true,0);
@ -576,6 +599,7 @@ instantiate(const LV2UI_Descriptor* descriptor,
ui->kits = scan_kits();
ui->gain_quark = g_quark_from_string("drmr_gain_quark");
ui->pan_quark = g_quark_from_string("drmr_pan_quark");
ui->trigger_quark = g_quark_from_string("drmr_trigger_quark");
ui->gain_sliders = NULL;
ui->pan_sliders = NULL;