- add input midi channel selection

This commit is contained in:
Arnaud G. GIBERT 2022-03-06 18:54:56 +01:00
parent c067a43b27
commit f405ce33ad
3 changed files with 125 additions and 21 deletions

38
drmr2.c
View File

@ -84,6 +84,7 @@ instantiate(const LV2_Descriptor* descriptor,
drmr->rate = rate; drmr->rate = rate;
drmr->ignore_velocity = false; drmr->ignore_velocity = false;
drmr->ignore_note_off = true; drmr->ignore_note_off = true;
drmr->channel_nb = 0;
#ifdef DRMR_UI_ZERO_SAMP #ifdef DRMR_UI_ZERO_SAMP
drmr->zero_position = DRMR_UI_ZERO_SAMP; drmr->zero_position = DRMR_UI_ZERO_SAMP;
@ -225,6 +226,8 @@ static inline LV2_Atom *build_state_message(DrMr *drmr) {
lv2_atom_forge_bool(&drmr->forge, drmr->ignore_velocity?true:false); lv2_atom_forge_bool(&drmr->forge, drmr->ignore_velocity?true:false);
lv2_atom_forge_property_head(&drmr->forge, drmr->uris.note_off_toggle,0); lv2_atom_forge_property_head(&drmr->forge, drmr->uris.note_off_toggle,0);
lv2_atom_forge_bool(&drmr->forge, drmr->ignore_note_off?true:false); lv2_atom_forge_bool(&drmr->forge, drmr->ignore_note_off?true:false);
lv2_atom_forge_property_head(&drmr->forge, drmr->uris.channel_nb,0);
lv2_atom_forge_int(&drmr->forge, drmr->channel_nb);
lv2_atom_forge_property_head(&drmr->forge, drmr->uris.zero_position,0); lv2_atom_forge_property_head(&drmr->forge, drmr->uris.zero_position,0);
lv2_atom_forge_int(&drmr->forge, drmr->zero_position); lv2_atom_forge_int(&drmr->forge, drmr->zero_position);
lv2_atom_forge_pop(&drmr->forge,&set_frame); lv2_atom_forge_pop(&drmr->forge,&set_frame);
@ -346,26 +349,38 @@ static void run(LV2_Handle instance, uint32_t n_samples) {
uint8_t nn; uint8_t nn;
uint8_t* const data = (uint8_t* const)(ev + 1); uint8_t* const data = (uint8_t* const)(ev + 1);
uint32_t offset = (ev->time.frames > 0 && ev->time.frames < n_samples) ? ev->time.frames : 0; uint32_t offset = (ev->time.frames > 0 && ev->time.frames < n_samples) ? ev->time.frames : 0;
//int channel = *data & 15; int channel = *data & 15;
switch ((*data) >> 4) {
if( ( drmr->channel_nb == 0) || ( channel == ( drmr->channel_nb - 1)))
{
switch ((*data) >> 4)
{
case 8: case 8:
{
if (!drmr->ignore_note_off) { if (!drmr->ignore_note_off) {
nn = data[1]; nn = data[1];
nn-=baseNote; nn-=baseNote;
untrigger_sample(drmr,nn,offset); untrigger_sample(drmr,nn,offset);
} }
break; break;
case 9: { }
case 9:
{
nn = data[1]; nn = data[1];
nn-=baseNote; nn-=baseNote;
trigger_sample(drmr,nn,data,offset); trigger_sample(drmr,nn,data,offset);
break; break;
} }
default: default:
{
//printf("Unhandeled status: %i\n",(*data)>>4); //printf("Unhandeled status: %i\n",(*data)>>4);
break; break;
} }
} }
}
}
else if (ev->body.type == drmr->uris.atom_resource) { else if (ev->body.type == drmr->uris.atom_resource) {
const LV2_Atom_Object *obj = (LV2_Atom_Object*)&ev->body; const LV2_Atom_Object *obj = (LV2_Atom_Object*)&ev->body;
if (obj->body.otype == drmr->uris.ui_msg) { if (obj->body.otype == drmr->uris.ui_msg) {
@ -373,12 +388,14 @@ static void run(LV2_Handle instance, uint32_t n_samples) {
const LV2_Atom* trigger = NULL; const LV2_Atom* trigger = NULL;
const LV2_Atom* ignvel = NULL; const LV2_Atom* ignvel = NULL;
const LV2_Atom* ignno = NULL; const LV2_Atom* ignno = NULL;
const LV2_Atom* channel_nb = NULL;
const LV2_Atom* zerop = NULL; const LV2_Atom* zerop = NULL;
lv2_atom_object_get(obj, lv2_atom_object_get(obj,
drmr->uris.kit_path, &path, drmr->uris.kit_path, &path,
drmr->uris.sample_trigger, &trigger, drmr->uris.sample_trigger, &trigger,
drmr->uris.velocity_toggle, &ignvel, drmr->uris.velocity_toggle, &ignvel,
drmr->uris.note_off_toggle, &ignno, drmr->uris.note_off_toggle, &ignno,
drmr->uris.channel_nb, &channel_nb,
drmr->uris.zero_position, &zerop, drmr->uris.zero_position, &zerop,
0); 0);
if (path) { if (path) {
@ -404,6 +421,8 @@ static void run(LV2_Handle instance, uint32_t n_samples) {
drmr->ignore_velocity = ((const LV2_Atom_Bool*)ignvel)->body; drmr->ignore_velocity = ((const LV2_Atom_Bool*)ignvel)->body;
if (ignno) if (ignno)
drmr->ignore_note_off = ((const LV2_Atom_Bool*)ignno)->body; drmr->ignore_note_off = ((const LV2_Atom_Bool*)ignno)->body;
if (channel_nb)
drmr->channel_nb = ((const LV2_Atom_Int*)channel_nb)->body;
if (zerop) if (zerop)
drmr->zero_position = ((const LV2_Atom_Int*)zerop)->body; drmr->zero_position = ((const LV2_Atom_Int*)zerop)->body;
} else if (obj->body.otype == drmr->uris.get_state) { } else if (obj->body.otype == drmr->uris.get_state) {
@ -572,6 +591,14 @@ save_state(LV2_Handle instance,
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
if (stat) return stat; if (stat) return stat;
stat = store(handle,
drmr->uris.channel_nb,
&drmr->channel_nb,
sizeof(int),
drmr->uris.int_urid,
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
if (stat) return stat;
stat = store(handle, stat = store(handle,
drmr->uris.zero_position, drmr->uris.zero_position,
&drmr->zero_position, &drmr->zero_position,
@ -639,6 +666,11 @@ restore_state(LV2_Handle instance,
if (ignore_note_off) if (ignore_note_off)
drmr->ignore_note_off = *ignore_note_off?true:false; drmr->ignore_note_off = *ignore_note_off?true:false;
const int* channel_nb =
retrieve(handle, drmr->uris.channel_nb, &size, &type, &fgs);
if (channel_nb)
drmr->channel_nb = *channel_nb;
const int* zero_position = const int* zero_position =
retrieve(handle, drmr->uris.zero_position, &size, &type, &fgs); retrieve(handle, drmr->uris.zero_position, &size, &type, &fgs);
if (zero_position) if (zero_position)

View File

@ -219,6 +219,7 @@ typedef struct {
LV2_URID sample_trigger; LV2_URID sample_trigger;
LV2_URID velocity_toggle; LV2_URID velocity_toggle;
LV2_URID note_off_toggle; LV2_URID note_off_toggle;
LV2_URID channel_nb;
LV2_URID zero_position; LV2_URID zero_position;
} drmr_uris; } drmr_uris;
@ -232,8 +233,10 @@ typedef struct {
LV2_Atom_Forge forge; LV2_Atom_Forge forge;
// params // params
int channel;
bool ignore_velocity; bool ignore_velocity;
bool ignore_note_off; bool ignore_note_off;
int channel_nb;
int zero_position; int zero_position;
float** gains; float** gains;
float** pans; float** pans;
@ -293,6 +296,9 @@ void map_drmr_uris(LV2_URID_Map *map,
uris->note_off_toggle = uris->note_off_toggle =
map->map(map->handle, map->map(map->handle,
DRMR_URI "#noteofftoggle"); DRMR_URI "#noteofftoggle");
uris->channel_nb =
map->map(map->handle,
DRMR_URI "#channelnb");
uris->zero_position = uris->zero_position =
map->map(map->handle, map->map(map->handle,
DRMR_URI "#zeroposition"); DRMR_URI "#zeroposition");

View File

@ -52,7 +52,7 @@ typedef struct {
GtkWidget** gain_sliders; GtkWidget** gain_sliders;
GtkWidget** pan_sliders; GtkWidget** pan_sliders;
GtkWidget** notify_leds; GtkWidget** notify_leds;
GtkWidget *position_combo_box, *velocity_checkbox, *note_off_checkbox; GtkWidget *channel_combo_box, *position_combo_box, *velocity_checkbox, *note_off_checkbox;
GtkScrolledWindow *sample_view; GtkScrolledWindow *sample_view;
float *gain_vals,*pan_vals; float *gain_vals,*pan_vals;
@ -60,6 +60,7 @@ typedef struct {
gchar *bundle_path; gchar *bundle_path;
int channel;
int cols; int cols;
int startSamp; int startSamp;
@ -417,10 +418,63 @@ static void kit_combobox_changed(GtkComboBox* box, gpointer data) {
} }
} }
static void channel_data(DrMrUi *ui, gpointer data) {
lv2_atom_forge_property_head(&ui->forge, ui->uris.channel_nb,0);
lv2_atom_forge_int(&ui->forge, GPOINTER_TO_INT(data));
}
static void channel_combobox_changed(GtkComboBox* box, gpointer data) {
DrMrUi* ui = (DrMrUi*)data;
gint channel = gtk_combo_box_get_active (GTK_COMBO_BOX(box));
printf( "Channel Change: [%d]\n", channel);
if (channel != ui->channel) {
ui->channel = channel;
ui->forceUpdate = true;
kit_callback(ui);
send_ui_msg(ui,&channel_data,GINT_TO_POINTER(channel));
}
}
static GtkWidget *create_channel_combo(void)
{
GtkWidget *combo;
GtkListStore *list_store;
GtkCellRenderer *cell;
GtkTreeIter iter;
int i;
char label[8];
list_store = gtk_list_store_new(1, G_TYPE_STRING);
gtk_list_store_append(list_store, &iter);
gtk_list_store_set (list_store, &iter, 0, "Omni", -1);
for( i = 1; i <= 16; i++) {
sprintf( label, "%02d", i);
gtk_list_store_append(list_store, &iter);
gtk_list_store_set (list_store, &iter, 0, label, -1);
}
combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(list_store));
gtk_combo_box_set_active(GTK_COMBO_BOX(combo),0);
g_object_unref(list_store);
cell = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), cell, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), cell, "text", 0, NULL);
return combo;
}
static void position_data(DrMrUi *ui, gpointer data) { static void position_data(DrMrUi *ui, gpointer data) {
lv2_atom_forge_property_head(&ui->forge, ui->uris.zero_position,0); lv2_atom_forge_property_head(&ui->forge, ui->uris.zero_position,0);
lv2_atom_forge_int(&ui->forge, GPOINTER_TO_INT(data)); lv2_atom_forge_int(&ui->forge, GPOINTER_TO_INT(data));
} }
static void position_combobox_changed(GtkComboBox* box, gpointer data) { static void position_combobox_changed(GtkComboBox* box, gpointer data) {
DrMrUi* ui = (DrMrUi*)data; DrMrUi* ui = (DrMrUi*)data;
gint ss = gtk_combo_box_get_active (GTK_COMBO_BOX(box)); gint ss = gtk_combo_box_get_active (GTK_COMBO_BOX(box));
@ -458,7 +512,6 @@ static GtkWidget *create_position_combo(void)
gtk_combo_box_set_active(GTK_COMBO_BOX(combo),0); gtk_combo_box_set_active(GTK_COMBO_BOX(combo),0);
#endif #endif
g_object_unref(list_store); g_object_unref(list_store);
cell = gtk_cell_renderer_text_new(); cell = gtk_cell_renderer_text_new();
@ -510,7 +563,7 @@ static void build_drmr_ui(DrMrUi* ui) {
GtkWidget *drmr_ui_widget; GtkWidget *drmr_ui_widget;
GtkWidget *opts_hbox1, *opts_hbox2, GtkWidget *opts_hbox1, *opts_hbox2,
*kit_combo_box, *kit_label, *no_kit_label, *kit_combo_box, *kit_label, *no_kit_label,
*base_label, *base_spin, *position_label, *sample_view; *base_label, *base_spin, *channel_label, *position_label, *sample_view;
GtkCellRenderer *cell_rend; GtkCellRenderer *cell_rend;
GtkAdjustment *base_adj; GtkAdjustment *base_adj;
@ -551,6 +604,9 @@ static void build_drmr_ui(DrMrUi* ui) {
5.0,0.0)); // page adj/size 5.0,0.0)); // page adj/size
base_spin = gtk_spin_button_new(base_adj, 1.0, 0); base_spin = gtk_spin_button_new(base_adj, 1.0, 0);
channel_label = gtk_label_new("Midi Channel: ");
ui->channel_combo_box = create_channel_combo();
position_label = gtk_label_new("Sample Zero Position: "); position_label = gtk_label_new("Sample Zero Position: ");
ui->position_combo_box = create_position_combo(); ui->position_combo_box = create_position_combo();
@ -568,6 +624,10 @@ static void build_drmr_ui(DrMrUi* ui) {
gtk_box_pack_start(GTK_BOX(opts_hbox1),base_spin, gtk_box_pack_start(GTK_BOX(opts_hbox1),base_spin,
true,true,0); true,true,0);
gtk_box_pack_start(GTK_BOX(opts_hbox2),channel_label,
false,false,15);
gtk_box_pack_start(GTK_BOX(opts_hbox2),ui->channel_combo_box,
false,false,0);
gtk_box_pack_start(GTK_BOX(opts_hbox2),position_label, gtk_box_pack_start(GTK_BOX(opts_hbox2),position_label,
false,false,15); false,false,15);
gtk_box_pack_start(GTK_BOX(opts_hbox2),ui->position_combo_box, gtk_box_pack_start(GTK_BOX(opts_hbox2),ui->position_combo_box,
@ -604,6 +664,7 @@ static void build_drmr_ui(DrMrUi* ui) {
g_signal_connect(G_OBJECT(kit_combo_box),"changed",G_CALLBACK(kit_combobox_changed),ui); g_signal_connect(G_OBJECT(kit_combo_box),"changed",G_CALLBACK(kit_combobox_changed),ui);
g_signal_connect(G_OBJECT(base_spin),"value-changed",G_CALLBACK(base_changed),ui); g_signal_connect(G_OBJECT(base_spin),"value-changed",G_CALLBACK(base_changed),ui);
g_signal_connect(G_OBJECT(ui->channel_combo_box),"changed",G_CALLBACK(channel_combobox_changed),ui);
g_signal_connect(G_OBJECT(ui->position_combo_box),"changed",G_CALLBACK(position_combobox_changed),ui); g_signal_connect(G_OBJECT(ui->position_combo_box),"changed",G_CALLBACK(position_combobox_changed),ui);
g_signal_connect(G_OBJECT(ui->velocity_checkbox),"toggled",G_CALLBACK(ignore_velocity_toggled),ui); g_signal_connect(G_OBJECT(ui->velocity_checkbox),"toggled",G_CALLBACK(ignore_velocity_toggled),ui);
g_signal_connect(G_OBJECT(ui->note_off_checkbox),"toggled",G_CALLBACK(ignore_note_off_toggled),ui); g_signal_connect(G_OBJECT(ui->note_off_checkbox),"toggled",G_CALLBACK(ignore_note_off_toggled),ui);
@ -755,10 +816,12 @@ port_event(LV2UI_Handle handle,
if (obj->body.otype == ui->uris.get_state) { // read out extra state info if (obj->body.otype == ui->uris.get_state) { // read out extra state info
const LV2_Atom* ignvel = NULL; const LV2_Atom* ignvel = NULL;
const LV2_Atom* ignno = NULL; const LV2_Atom* ignno = NULL;
const LV2_Atom* channel_nb = NULL;
const LV2_Atom* zerop = NULL; const LV2_Atom* zerop = NULL;
lv2_atom_object_get(obj, lv2_atom_object_get(obj,
ui->uris.velocity_toggle, &ignvel, ui->uris.velocity_toggle, &ignvel,
ui->uris.note_off_toggle, &ignno, ui->uris.note_off_toggle, &ignno,
ui->uris.channel_nb, &channel_nb,
ui->uris.zero_position, &zerop, ui->uris.zero_position, &zerop,
0); 0);
if (ignvel) if (ignvel)
@ -767,6 +830,9 @@ port_event(LV2UI_Handle handle,
if (ignno) if (ignno)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ui->note_off_checkbox), gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ui->note_off_checkbox),
((const LV2_Atom_Bool*)ignno)->body); ((const LV2_Atom_Bool*)ignno)->body);
if (channel_nb)
gtk_combo_box_set_active(GTK_COMBO_BOX(ui->channel_combo_box),
((const LV2_Atom_Int*)channel_nb)->body);
if (zerop) if (zerop)
gtk_combo_box_set_active(GTK_COMBO_BOX(ui->position_combo_box), gtk_combo_box_set_active(GTK_COMBO_BOX(ui->position_combo_box),
((const LV2_Atom_Int*)zerop)->body); ((const LV2_Atom_Int*)zerop)->body);