For consistency, treat notes like the other messages having a parameter value, so that they can be used in data translations.

master
Albert Graef 2018-08-28 10:14:55 +02:00
parent 898043def8
commit 832e98266c
3 changed files with 151 additions and 32 deletions

141
midizap.c
View File

@ -60,6 +60,7 @@ send_key(KeySym key, int press)
}
// cached controller and pitch bend values
static int16_t notevalue[16][128];
static int16_t ccvalue[16][128];
static int16_t kpvalue[16][128];
static int16_t cpvalue[16];
@ -104,7 +105,22 @@ send_midi(uint8_t portno, int status, int data,
msg[1] = data;
switch (status & 0xf0) {
case 0x90:
if (mod) {
if (dir) {
// increment (dir==1) or decrement (dir==-1) the current value,
// clamping it to the 0..127 data byte range
if (!step) step = 1;
dir *= step;
if (dir > 0) {
if (notevalue[chan][data] >= 127) return;
notevalue[chan][data] += dir;
if (notevalue[chan][data] > 127) notevalue[chan][data] = 127;
} else {
if (notevalue[chan][data] == 0) return;
notevalue[chan][data] += dir;
if (notevalue[chan][data] < 0) notevalue[chan][data] = 0;
}
msg[2] = kpvalue[chan][data];
} else if (mod) {
int d = msg[1] + datavals(val/mod, mod_step, mod_steps, mod_n_steps);
int v = datavals(val%mod, step, steps, n_steps);
if (d > 127 || d < 0) return;
@ -318,6 +334,13 @@ static stroke *find_note(translation *tr, int shift,
tr->n_note[shift]);
}
static stroke *find_notes(translation *tr, int shift,
int chan, int data, int index, int *step)
{
return find_stroke_data(tr->notes[shift], chan, data, index, step, 0, 0, 0, 0,
tr->n_notes[shift]);
}
static stroke *find_pc(translation *tr, int shift,
int chan, int data, int index)
{
@ -398,7 +421,10 @@ fetch_stroke(translation *tr, uint8_t portno, int status, int chan, int data,
if (tr && tr->portno == portno) {
switch (status) {
case 0x90:
return find_note(tr, shift, chan, data, index, mod, step, n_steps, steps);
if (dir)
return find_notes(tr, shift, chan, data, dir>0, step);
else
return find_note(tr, shift, chan, data, index, mod, step, n_steps, steps);
case 0xc0:
return find_pc(tr, shift, chan, data, index);
case 0xb0:
@ -484,8 +510,21 @@ static char *debug_key(translation *tr, char *name,
switch (status) {
case 0x90: {
int mod = 0, step, n_steps, *steps;
(void)find_note(tr, shift, chan, data, 0, &mod, &step, &n_steps, &steps);
if (mod)
if (tr) {
if (dir) {
step = 1;
(void)find_notes(tr, shift, chan, data, dir>0, &step);
} else
(void)find_note(tr, shift, chan, data, 0, &mod, &step, &n_steps, &steps);
}
if (!dir)
suffix = "";
else
suffix = (dir<0)?"-":"+";
if (dir && step != 1)
sprintf(name, "%s%s%d[%d]-%d%s", prefix, note_name(data),
note_octave(data), step, chan+1, suffix);
else if (!dir && mod)
if (step != 1)
sprintf(name, "%s%s%d[%d][%d]-%d", prefix, note_name(data),
note_octave(data), mod, step, chan+1);
@ -500,8 +539,8 @@ static char *debug_key(translation *tr, char *name,
sprintf(name, "%s%s%d[%d]-%d", prefix, note_name(data),
note_octave(data), mod, chan+1);
else
sprintf(name, "%s%s%d-%d", prefix, note_name(data),
note_octave(data), chan+1);
sprintf(name, "%s%s%d-%d%s", prefix, note_name(data),
note_octave(data), chan+1, suffix);
break;
}
case 0xa0: {
@ -841,6 +880,7 @@ get_focused_window_translation()
return last_window_translation;
}
static int8_t innotevalue[2][16][128];
static int8_t inccvalue[2][16][128];
static int8_t inkpvalue[2][16][128];
static int8_t incpvalue[2][16];
@ -857,12 +897,50 @@ static int16_t inpbvalue[2][16] =
static int keydown_tracker = 0;
static uint8_t notedown[2][16][128];
static uint8_t innotedown[2][16][128];
static uint8_t inccdown[2][16][128];
static uint8_t inpbdown[2][16];
static uint8_t inkpdown[2][16][128];
static uint8_t incpdown[2][16];
int
check_notes(translation *tr, uint8_t portno, int chan, int data)
{
if (tr && tr->portno == portno &&
(find_notes(tr, shift, chan, data, 0, 0) ||
find_notes(tr, shift, chan, data, 1, 0)))
return 1;
tr = default_midi_translation[portno];
if (tr && tr->portno == portno &&
(find_notes(tr, shift, chan, data, 0, 0) ||
find_notes(tr, shift, chan, data, 1, 0)))
return 1;
tr = default_translation;
if (tr && tr->portno == portno &&
(find_notes(tr, shift, chan, data, 0, 0) ||
find_notes(tr, shift, chan, data, 1, 0)))
return 1;
return 0;
}
int
get_note_step(translation *tr, uint8_t portno, int chan, int data, int dir)
{
int step;
if (tr && tr->portno == portno &&
find_notes(tr, shift, chan, data, dir>0, &step))
return step;
tr = default_midi_translation[portno];
if (tr && tr->portno == portno &&
find_notes(tr, shift, chan, data, dir>0, &step))
return step;
tr = default_translation;
if (tr && tr->portno == portno &&
find_notes(tr, shift, chan, data, dir>0, &step))
return step;
return 1;
}
int
get_note_mod(translation *tr, uint8_t portno, int chan, int data)
{
@ -1147,23 +1225,6 @@ handle_event(uint8_t *msg, uint8_t portno)
send_strokes(tr, portno, status, chan, msg[1], 0, 1, 0);
end_debug();
break;
case 0x90:
start_debug();
if (get_note_mod(tr, portno, chan, msg[1]))
send_strokes(tr, portno, status, chan, msg[1], msg[2], 0, 0);
else if (msg[2]) {
if (!keydown_tracker || !notedown[portno][chan][msg[1]]) {
send_strokes(tr, portno, status, chan, msg[1], msg[2], 0, 0);
notedown[portno][chan][msg[1]] = 1;
}
} else {
if (!keydown_tracker || notedown[portno][chan][msg[1]]) {
send_strokes(tr, portno, status, chan, msg[1], msg[2], 1, 0);
notedown[portno][chan][msg[1]] = 0;
}
}
end_debug();
break;
case 0xb0:
start_debug();
if (get_cc_mod(tr, portno, chan, msg[1]))
@ -1227,6 +1288,38 @@ handle_event(uint8_t *msg, uint8_t portno)
}
end_debug();
break;
case 0x90:
start_debug();
if (get_note_mod(tr, portno, chan, msg[1]))
send_strokes(tr, portno, status, chan, msg[1], msg[2], 0, 0);
else if (msg[2]) {
if (!keydown_tracker || !innotedown[portno][chan][msg[1]]) {
send_strokes(tr, portno, status, chan, msg[1], msg[2], 0, 0);
innotedown[portno][chan][msg[1]] = 1;
}
} else {
if (!keydown_tracker || innotedown[portno][chan][msg[1]]) {
send_strokes(tr, portno, status, chan, msg[1], msg[2], 1, 0);
innotedown[portno][chan][msg[1]] = 0;
}
}
debug_count = 0;
if (check_notes(tr, portno, chan, msg[1]) &&
innotevalue[portno][chan][msg[1]] != msg[2]) {
int dir = innotevalue[portno][chan][msg[1]] > msg[2] ? -1 : 1;
int step = get_note_step(tr, portno, chan, msg[1], dir);
if (step) {
while (innotevalue[portno][chan][msg[1]] != msg[2]) {
int d = abs(innotevalue[portno][chan][msg[1]] - msg[2]);
if (d > step) d = step;
if (d < step) break;
send_strokes(tr, portno, status, chan, msg[1], 0, 0, dir);
innotevalue[portno][chan][msg[1]] += dir*d;
}
}
}
end_debug();
break;
case 0xa0:
start_debug();
if (get_kp_mod(tr, portno, chan, msg[1]))

View File

@ -85,6 +85,7 @@ typedef struct _translation {
uint8_t portno;
// these are indexed by shift status
stroke_data *note[2];
stroke_data *notes[2];
stroke_data *pc[2];
stroke_data *cc[2];
stroke_data *ccs[2];
@ -95,10 +96,10 @@ typedef struct _translation {
stroke_data *cp[2];
stroke_data *cps[2];
// actual and allocated sizes (can be at most 16*128)
uint16_t n_note[2], n_pc[2], n_cc[2], n_ccs[2], n_pb[2], n_pbs[2],
n_kp[2], n_kps[2], n_cp[2], n_cps[2];
uint16_t a_note[2], a_pc[2], a_cc[2], a_ccs[2], a_pb[2], a_pbs[2],
a_kp[2], a_kps[2], a_cp[2], a_cps[2];
uint16_t n_note[2], n_notes[2], n_pc[2], n_cc[2], n_ccs[2],
n_pb[2], n_pbs[2], n_kp[2], n_kps[2], n_cp[2], n_cps[2];
uint16_t a_note[2], a_notes[2], a_pc[2], a_cc[2], a_ccs[2],
a_pb[2], a_pbs[2], a_kp[2], a_kps[2], a_cp[2], a_cps[2];
} translation;
extern void reload_callback(void);

View File

@ -296,6 +296,14 @@ static stroke **find_note(translation *tr, int shift,
&tr->n_note[shift], &tr->a_note[shift]);
}
static stroke **find_notes(translation *tr, int shift,
int chan, int data, int index, int step)
{
return find_stroke_data(&tr->notes[shift], chan, data, index, step,
0, 0, 0, 0,
&tr->n_notes[shift], &tr->a_notes[shift]);
}
static stroke **find_pc(translation *tr, int shift,
int chan, int data, int index)
{
@ -1034,10 +1042,10 @@ parse_midi(char *tok, char *s, int lhs, int mode,
return 0;
}
}
// incremental flag ("cc", "pb", "cp" and "kp" only)
// incremental flag (messages with data only, not "ch" or "pc")
if (*p && strchr("+-=<>~", *p)) {
if (strcmp(s, "pb") && strcmp(s, "cc") &&
strcmp(s, "cp") && strcmp(s, "kp")) return 0;
if (strcmp(s, "ch") == 0) return 0;
if (strcmp(s, "pc") == 0) return 0;
// these are only permitted with "cc"
if (strchr("<>~", *p) && strcmp(s, "cc")) return 0;
if (lhs) {
@ -1166,7 +1174,24 @@ start_translation(translation *tr, char *which_key)
mode = incr?0:mod?2:1;
switch (status & 0xf0) {
case 0x90:
if (mod) {
if (incr) {
// note (step up, down)
if (step <= 0) {
fprintf(stderr, "zero or negative step size not permitted here: [%s]%s\n", current_translation, which_key);
return 1;
}
first_stroke = find_notes(tr, k, chan, data, dir>0, step);
if (is_anyshift) {
alt_press_stroke = find_notes(tr, 0, chan, data, dir>0, step);
}
if (!dir) {
is_bidirectional = 1;
release_first_stroke = find_notes(tr, k, chan, data, 1, step);
if (is_anyshift) {
alt_release_stroke = find_notes(tr, 0, chan, data, 1, step);
}
}
} else if (mod) {
// note mod
first_stroke = find_note(tr, k, chan, data, 0, mod,
step, n_steps, steps);