diff --git a/drmr.c b/drmr.c index 6194ee9..d68361b 100644 --- a/drmr.c +++ b/drmr.c @@ -126,6 +126,8 @@ connect_port(LV2_Handle instance, case DRMR_KITNUM: if(data) drmr->kitReq = (float*)data; break; + case DRMR_BASENOTE: + if (data) drmr->baseNote = (float*)data; default: break; } @@ -169,10 +171,11 @@ 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; + int i,kitInt,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); @@ -190,7 +193,7 @@ static void run(LV2_Handle instance, uint32_t n_samples) { break; case 9: { uint8_t nn = data[1]; - nn-=60; // middle c is our root note (setting?) + 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); diff --git a/drmr.h b/drmr.h index b5714eb..3ac7a21 100644 --- a/drmr.h +++ b/drmr.h @@ -70,6 +70,7 @@ typedef enum { DRMR_LEFT, DRMR_RIGHT, DRMR_KITNUM, + DRMR_BASENOTE, DRMR_GAIN_ONE, DRMR_GAIN_TWO, DRMR_GAIN_THREE, @@ -147,6 +148,7 @@ typedef struct { float** gains; float** pans; float* kitReq; + float* baseNote; double rate; // URIs diff --git a/drmr.ttl b/drmr.ttl index 8c76c21..bbe4100 100644 --- a/drmr.ttl +++ b/drmr.ttl @@ -44,14 +44,26 @@ lv2:symbol "kit_num"; lv2:name "Kit Index"; lv2:minimum 0; - lv2:maximum 50; + lv2:maximum 200; lv2:default 0; lv2:portProperty lv2:integer; ], + + [ + a lv2:ControlPort, lv2:InputPort; + lv2:index 4; + lv2:symbol "base_note"; + lv2:name "Midi Base Note"; + lv2:minimum 21; + lv2:maximum 107; + lv2:default 36; + lv2:portProperty lv2:integer; + ], + [ a lv2:ControlPort, lv2:InputPort; - lv2:index 4; + lv2:index 5; lv2:symbol "gain_one"; lv2:name "Sample One Gain"; lv2:minimum -60.0; @@ -65,7 +77,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 5; + lv2:index 6; lv2:symbol "gain_two"; lv2:name "Sample Two Gain"; lv2:minimum -60.0; @@ -79,7 +91,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 6; + lv2:index 7; lv2:symbol "gain_three"; lv2:name "Sample Three Gain"; lv2:minimum -60.0; @@ -93,7 +105,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 7; + lv2:index 8; lv2:symbol "gain_four"; lv2:name "Sample Four Gain"; lv2:minimum -60.0; @@ -107,7 +119,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 8; + lv2:index 9; lv2:symbol "gain_five"; lv2:name "Sample Five Gain"; lv2:minimum -60.0; @@ -121,7 +133,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 9; + lv2:index 10; lv2:symbol "gain_six"; lv2:name "Sample Six Gain"; lv2:minimum -60.0; @@ -135,7 +147,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 10; + lv2:index 11; lv2:symbol "gain_seven"; lv2:name "Sample Seven Gain"; lv2:minimum -60.0; @@ -149,7 +161,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 11; + lv2:index 12; lv2:symbol "gain_eight"; lv2:name "Sample Eight Gain"; lv2:minimum -60.0; @@ -163,7 +175,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 12; + lv2:index 13; lv2:symbol "gain_nine"; lv2:name "Sample Nine Gain"; lv2:minimum -60.0; @@ -177,7 +189,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 13; + lv2:index 14; lv2:symbol "gain_ten"; lv2:name "Sample Ten Gain"; lv2:minimum -60.0; @@ -191,7 +203,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 14; + lv2:index 15; lv2:symbol "gain_eleven"; lv2:name "Sample Eleven Gain"; lv2:minimum -60.0; @@ -205,7 +217,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 15; + lv2:index 16; lv2:symbol "gain_twelve"; lv2:name "Sample Twelve Gain"; lv2:minimum -60.0; @@ -219,7 +231,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 16; + lv2:index 17; lv2:symbol "gain_thirteen"; lv2:name "Sample Thirteen Gain"; lv2:minimum -60.0; @@ -233,7 +245,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 17; + lv2:index 18; lv2:symbol "gain_fourteen"; lv2:name "Sample Fourteen Gain"; lv2:minimum -60.0; @@ -247,7 +259,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 18; + lv2:index 19; lv2:symbol "gain_fifteen"; lv2:name "Sample Fifteen Gain"; lv2:minimum -60.0; @@ -261,7 +273,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 19; + lv2:index 20; lv2:symbol "gain_sixteen"; lv2:name "Sample Sixteen Gain"; lv2:minimum -60.0; @@ -275,7 +287,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 20; + lv2:index 21; lv2:symbol "gain_seventeen"; lv2:name "Sample Seventeen Gain"; lv2:minimum -60.0; @@ -290,7 +302,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 21; + lv2:index 22; lv2:symbol "gain_eighteen"; lv2:name "Sample Eighteen Gain"; lv2:minimum -60.0; @@ -304,7 +316,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 22; + lv2:index 23; lv2:symbol "gain_nineteen"; lv2:name "Sample Nineteen Gain"; lv2:minimum -60.0; @@ -318,7 +330,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 23; + lv2:index 24; lv2:symbol "gain_twenty"; lv2:name "Sample Twenty Gain"; lv2:minimum -60.0; @@ -332,7 +344,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 24; + lv2:index 25; lv2:symbol "gain_twentyone"; lv2:name "Sample Twenty One Gain"; lv2:minimum -60.0; @@ -346,7 +358,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 25; + lv2:index 26; lv2:symbol "gain_twentytwo"; lv2:name "Sample Twenty Two Gain"; lv2:minimum -60.0; @@ -360,7 +372,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 26; + lv2:index 27; lv2:symbol "gain_twentythree"; lv2:name "Sample Twenty Three Gain"; lv2:minimum -60.0; @@ -374,7 +386,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 27; + lv2:index 28; lv2:symbol "gain_twentyfour"; lv2:name "Sample Twenty Four Gain"; lv2:minimum -60.0; @@ -388,7 +400,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 28; + lv2:index 29; lv2:symbol "gain_twentyfive"; lv2:name "Sample Twenty Five Gain"; lv2:minimum -60.0; @@ -402,7 +414,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 29; + lv2:index 30; lv2:symbol "gain_twentysix"; lv2:name "Sample Twenty Six Gain"; lv2:minimum -60.0; @@ -416,7 +428,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 30; + lv2:index 31; lv2:symbol "gain_twentyseven"; lv2:name "Sample Twenty Seven Gain"; lv2:minimum -60.0; @@ -430,7 +442,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 31; + lv2:index 32; lv2:symbol "gain_twentyeight"; lv2:name "Sample Twenty Eight Gain"; lv2:minimum -60.0; @@ -444,7 +456,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 32; + lv2:index 33; lv2:symbol "gain_twentynine"; lv2:name "Sample Twenty Nine Gain"; lv2:minimum -60.0; @@ -458,7 +470,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 33; + lv2:index 34; lv2:symbol "gain_thirty"; lv2:name "Sample Thirty Gain"; lv2:minimum -60.0; @@ -472,7 +484,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 34; + lv2:index 35; lv2:symbol "gain_thirtyone"; lv2:name "Sample Thirty One Gain"; lv2:minimum -60.0; @@ -486,7 +498,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 35; + lv2:index 36; lv2:symbol "gain_thirtytwo"; lv2:name "Sample Thirty Two Gain"; lv2:minimum -60.0; @@ -500,7 +512,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 36; + lv2:index 37; lv2:symbol "pan_one"; lv2:name "Sample One Pan"; lv2:minimum -1.0; @@ -510,7 +522,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 37; + lv2:index 38; lv2:symbol "pan_two"; lv2:name "Sample Two Pan"; lv2:minimum -1.0; @@ -520,7 +532,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 38; + lv2:index 39; lv2:symbol "pan_three"; lv2:name "Sample Three Pan"; lv2:minimum -1.0; @@ -530,7 +542,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 39; + lv2:index 40; lv2:symbol "pan_four"; lv2:name "Sample Four Pan"; lv2:minimum -1.0; @@ -540,7 +552,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 40; + lv2:index 41; lv2:symbol "pan_five"; lv2:name "Sample Five Pan"; lv2:minimum -1.0; @@ -550,7 +562,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 41; + lv2:index 42; lv2:symbol "pan_six"; lv2:name "Sample Six Pan"; lv2:minimum -1.0; @@ -560,7 +572,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 42; + lv2:index 43; lv2:symbol "pan_seven"; lv2:name "Sample Seven Pan"; lv2:minimum -1.0; @@ -570,7 +582,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 43; + lv2:index 44; lv2:symbol "pan_eight"; lv2:name "Sample Eight Pan"; lv2:minimum -1.0; @@ -580,7 +592,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 44; + lv2:index 45; lv2:symbol "pan_nine"; lv2:name "Sample Nine Pan"; lv2:minimum -1.0; @@ -590,7 +602,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 45; + lv2:index 46; lv2:symbol "pan_ten"; lv2:name "Sample Ten Pan"; lv2:minimum -1.0; @@ -600,7 +612,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 46; + lv2:index 47; lv2:symbol "pan_eleven"; lv2:name "Sample Eleven Pan"; lv2:minimum -1.0; @@ -610,7 +622,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 47; + lv2:index 48; lv2:symbol "pan_twelve"; lv2:name "Sample Twelve Pan"; lv2:minimum -1.0; @@ -620,7 +632,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 48; + lv2:index 49; lv2:symbol "pan_thirteen"; lv2:name "Sample Thirteen Pan"; lv2:minimum -1.0; @@ -630,7 +642,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 49; + lv2:index 50; lv2:symbol "pan_fourteen"; lv2:name "Sample Fourteen Pan"; lv2:minimum -1.0; @@ -640,7 +652,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 50; + lv2:index 51; lv2:symbol "pan_fifteen"; lv2:name "Sample Fifteen Pan"; lv2:minimum -1.0; @@ -650,7 +662,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 51; + lv2:index 52; lv2:symbol "pan_sixteen"; lv2:name "Sample Sixteen Pan"; lv2:minimum -1.0; @@ -660,7 +672,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 52; + lv2:index 53; lv2:symbol "pan_seventeen"; lv2:name "Sample Seventeen Pan"; lv2:minimum -1.0; @@ -675,7 +687,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 53; + lv2:index 54; lv2:symbol "pan_eighteen"; lv2:name "Sample Eighteen Pan"; lv2:minimum -1.0; @@ -689,7 +701,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 54; + lv2:index 55; lv2:symbol "pan_nineteen"; lv2:name "Sample Nineteen Pan"; lv2:minimum -1.0; @@ -703,7 +715,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 55; + lv2:index 56; lv2:symbol "pan_twenty"; lv2:name "Sample Twenty Pan"; lv2:minimum -1.0; @@ -717,7 +729,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 56; + lv2:index 57; lv2:symbol "pan_twentyone"; lv2:name "Sample Twenty One Pan"; lv2:minimum -1.0; @@ -731,7 +743,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 57; + lv2:index 58; lv2:symbol "pan_twentytwo"; lv2:name "Sample Twenty Two Pan"; lv2:minimum -1.0; @@ -745,7 +757,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 58; + lv2:index 59; lv2:symbol "pan_twentythree"; lv2:name "Sample Twenty Three Pan"; lv2:minimum -1.0; @@ -759,7 +771,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 59; + lv2:index 60; lv2:symbol "pan_twentyfour"; lv2:name "Sample Twenty Four Pan"; lv2:minimum -1.0; @@ -773,7 +785,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 60; + lv2:index 61; lv2:symbol "pan_twentyfive"; lv2:name "Sample Twenty Five Pan"; lv2:minimum -1.0; @@ -787,7 +799,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 61; + lv2:index 62; lv2:symbol "pan_twentysix"; lv2:name "Sample Twenty Six Pan"; lv2:minimum -1.0; @@ -801,7 +813,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 62; + lv2:index 63; lv2:symbol "pan_twentyseven"; lv2:name "Sample Twenty Seven Pan"; lv2:minimum -1.0; @@ -815,7 +827,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 63; + lv2:index 64; lv2:symbol "pan_twentyeight"; lv2:name "Sample Twenty Eight Pan"; lv2:minimum -1.0; @@ -829,7 +841,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 64; + lv2:index 65; lv2:symbol "pan_twentynine"; lv2:name "Sample Twenty Nine Pan"; lv2:minimum -1.0; @@ -843,7 +855,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 65; + lv2:index 66; lv2:symbol "pan_thirty"; lv2:name "Sample Thirty Pan"; lv2:minimum -1.0; @@ -857,7 +869,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 66; + lv2:index 67; lv2:symbol "pan_thirtyone"; lv2:name "Sample Thirty One Pan"; lv2:minimum -1.0; @@ -871,7 +883,7 @@ [ a lv2:ControlPort, lv2:InputPort; - lv2:index 67; + lv2:index 68; lv2:symbol "pan_thirtytwo"; lv2:name "Sample Thirty Two Pan"; lv2:minimum -1.0; diff --git a/drmr_ui.c b/drmr_ui.c index 78d33a5..6bcb46d 100644 --- a/drmr_ui.c +++ b/drmr_ui.c @@ -31,6 +31,7 @@ typedef struct { GtkWidget *drmr_widget; GtkTable *sample_table; GtkComboBox *kit_combo; + GtkLabel *base_label; GtkListStore *kit_store; GtkWidget** gain_sliders; GtkWidget** pan_sliders; @@ -122,7 +123,7 @@ static void fill_sample_table(DrMrUi* ui, int samples, GtkWidget** gain_sliders, } } -void kit_combobox_changed(GtkComboBox* box, gpointer data) { +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; @@ -130,6 +131,28 @@ void kit_combobox_changed(GtkComboBox* box, gpointer data) { ui->write(ui->controller,DRMR_KITNUM,4,0,&fkit); } +static const char* nstrs = "C C#D D#E F F#G G#A A#B "; +static char baseLabelBuf[32]; +static void setBaseLabel(int noteIdx) { + int oct = (noteIdx/12)-1; + int nmt = (noteIdx%12)*2; + snprintf(baseLabelBuf,32,"Midi Base Note (%c%c%i):", + nstrs[nmt],nstrs[nmt+1],oct); +} + +static void base_changed(GtkSpinButton *base_spin, gpointer data) { + DrMrUi* ui = (DrMrUi*)data; + float base = (float)gtk_spin_button_get_value(base_spin); + + if (base >= 21.0f && base <= 107.0f) { + setBaseLabel((int)base); + ui->write(ui->controller,DRMR_BASENOTE,4,0,&base); + gtk_label_set_markup(ui->base_label,baseLabelBuf); + } + else + fprintf(stderr,"Base spin got out of range: %f\n",base); +} + static void fill_kit_combo(GtkComboBox* combo, kits* kits) { int i; GtkTreeIter iter; @@ -142,15 +165,16 @@ static void fill_kit_combo(GtkComboBox* combo, kits* kits) { static void build_drmr_ui(DrMrUi* ui) { GtkWidget *drmr_ui_widget; - GtkWidget *kit_hbox, *kit_combo_box, *kit_label; + GtkWidget *opts_hbox, *kit_combo_box, *kit_label, *base_label, *base_spin; GtkCellRenderer *cell_rend; + GtkAdjustment *base_adj; drmr_ui_widget = gtk_vbox_new(false,0); g_object_set(drmr_ui_widget,"border-width",6,NULL); ui->kit_store = gtk_list_store_new(1,G_TYPE_STRING); - kit_hbox = gtk_hbox_new(false,0); + opts_hbox = gtk_hbox_new(false,0); kit_combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(ui->kit_store)); kit_label = gtk_label_new("Kit:"); @@ -158,19 +182,35 @@ static void build_drmr_ui(DrMrUi* ui) { gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(kit_combo_box), cell_rend, true); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(kit_combo_box), cell_rend,"text",0,NULL); - gtk_box_pack_start(GTK_BOX(kit_hbox),kit_label, + base_label = gtk_label_new("Midi Base Note (C 2):"); + gtk_label_set_use_markup(GTK_LABEL(base_label),true); + base_adj = GTK_ADJUSTMENT + (gtk_adjustment_new(36.0, // val + 21.0,107.0, // min/max + 1.0, // step + 5.0,5.0)); // page adj/size + base_spin = gtk_spin_button_new(base_adj, 1.0, 0); + + gtk_box_pack_start(GTK_BOX(opts_hbox),kit_label, false,false,15); - gtk_box_pack_start(GTK_BOX(kit_hbox),kit_combo_box, + gtk_box_pack_start(GTK_BOX(opts_hbox),kit_combo_box, true,true,0); - gtk_box_pack_start(GTK_BOX(drmr_ui_widget),kit_hbox, + gtk_box_pack_start(GTK_BOX(opts_hbox),base_label, + false,false,15); + gtk_box_pack_start(GTK_BOX(opts_hbox),base_spin, + true,true,0); + gtk_box_pack_start(GTK_BOX(drmr_ui_widget),opts_hbox, false,false,5); + ui->drmr_widget = drmr_ui_widget; ui->sample_table = NULL; ui->kit_combo = GTK_COMBO_BOX(kit_combo_box); + ui->base_label = GTK_LABEL(base_label); 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); gtk_widget_show_all(drmr_ui_widget); }