Add support for direct feedback.
This commit is contained in:
parent
7c9147b4d4
commit
f2aedd6267
|
@ -24,7 +24,7 @@ SYSTEM_PASSTHROUGH # pass through MCP feedback
|
||||||
|
|
||||||
# We use the Mk3's dedicated SHIFT button as our primary shift key, to provide
|
# We use the Mk3's dedicated SHIFT button as our primary shift key, to provide
|
||||||
# alternative functions to some of the buttons and the faders.
|
# alternative functions to some of the buttons and the faders.
|
||||||
?F2 SHIFT RELEASE SHIFT
|
?F2 SHIFT ^F2 RELEASE SHIFT ^F2
|
||||||
|
|
||||||
# transport (assigned to the transport section on the bottom left)
|
# transport (assigned to the transport section on the bottom left)
|
||||||
F#5 A7 # Stop
|
F#5 A7 # Stop
|
||||||
|
@ -79,11 +79,12 @@ C2 E8 # Zoom
|
||||||
# The Mk3 has one row of dedicated "channel buttons" at the top, right above
|
# The Mk3 has one row of dedicated "channel buttons" at the top, right above
|
||||||
# the display. Since we'd also like to use these for the channel-based
|
# the display. Since we'd also like to use these for the channel-based
|
||||||
# rec/solo/mute functions, we combine them with the SELECT, SOLO and MUTE
|
# rec/solo/mute functions, we combine them with the SELECT, SOLO and MUTE
|
||||||
# buttons as additional shift keys.
|
# buttons as additional shift keys. These are "Caps Lock"-style keys which
|
||||||
|
# stay on until pressed again.
|
||||||
|
|
||||||
?F#4 SHIFT2 RELEASE SHIFT2
|
?F#4 SHIFT2 ^F#4
|
||||||
?G4 SHIFT3 RELEASE SHIFT3
|
?G4 SHIFT3 ^G4
|
||||||
?G#4 SHIFT4 RELEASE SHIFT4
|
?G#4 SHIFT4 ^G#4
|
||||||
|
|
||||||
# top row, unshifted: track select
|
# top row, unshifted: track select
|
||||||
G6 C2
|
G6 C2
|
||||||
|
|
155
midizap.c
155
midizap.c
|
@ -21,7 +21,7 @@ Display *display;
|
||||||
|
|
||||||
JACK_SEQ seq;
|
JACK_SEQ seq;
|
||||||
int jack_num_outputs = 0, debug_jack = 0;
|
int jack_num_outputs = 0, debug_jack = 0;
|
||||||
int direct_feedback = 1, system_passthrough = 0;
|
int auto_feedback = 1, system_passthrough = 0;
|
||||||
int shift = 0;
|
int shift = 0;
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -61,13 +61,15 @@ send_key(KeySym key, int press)
|
||||||
}
|
}
|
||||||
|
|
||||||
// cached controller and pitch bend values
|
// cached controller and pitch bend values
|
||||||
static int16_t notevalue[16][128];
|
static int16_t notevalue[2][16][128];
|
||||||
static int16_t ccvalue[16][128];
|
static int16_t ccvalue[2][16][128];
|
||||||
static int16_t kpvalue[16][128];
|
static int16_t kpvalue[2][16][128];
|
||||||
static int16_t cpvalue[16];
|
static int16_t cpvalue[2][16];
|
||||||
static int16_t pbvalue[16] =
|
static int16_t pbvalue[2][16] =
|
||||||
{8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
|
{{8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
|
||||||
8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192};
|
8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192},
|
||||||
|
{8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
|
||||||
|
8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192}};
|
||||||
|
|
||||||
static int dataval(int val, int min, int max)
|
static int dataval(int val, int min, int max)
|
||||||
{
|
{
|
||||||
|
@ -102,7 +104,8 @@ send_midi(uint8_t portno, int status, int data,
|
||||||
int incr, int index, int dir,
|
int incr, int index, int dir,
|
||||||
int mod, int mod_step, int mod_n_steps, int *mod_steps,
|
int mod, int mod_step, int mod_n_steps, int *mod_steps,
|
||||||
int val, int swap,
|
int val, int swap,
|
||||||
int recursive, int depth)
|
int recursive, int depth,
|
||||||
|
uint8_t ret_msg[3])
|
||||||
{
|
{
|
||||||
if (!jack_num_outputs) return; // MIDI output not enabled
|
if (!jack_num_outputs) return; // MIDI output not enabled
|
||||||
uint8_t msg[3];
|
uint8_t msg[3];
|
||||||
|
@ -117,15 +120,15 @@ send_midi(uint8_t portno, int status, int data,
|
||||||
if (!step) step = 1;
|
if (!step) step = 1;
|
||||||
dir *= step;
|
dir *= step;
|
||||||
if (dir > 0) {
|
if (dir > 0) {
|
||||||
if (notevalue[chan][data] >= 127) return;
|
if (notevalue[portno][chan][data] >= 127) return;
|
||||||
notevalue[chan][data] += dir;
|
notevalue[portno][chan][data] += dir;
|
||||||
if (notevalue[chan][data] > 127) notevalue[chan][data] = 127;
|
if (notevalue[portno][chan][data] > 127) notevalue[portno][chan][data] = 127;
|
||||||
} else {
|
} else {
|
||||||
if (notevalue[chan][data] == 0) return;
|
if (notevalue[portno][chan][data] == 0) return;
|
||||||
notevalue[chan][data] += dir;
|
notevalue[portno][chan][data] += dir;
|
||||||
if (notevalue[chan][data] < 0) notevalue[chan][data] = 0;
|
if (notevalue[portno][chan][data] < 0) notevalue[portno][chan][data] = 0;
|
||||||
}
|
}
|
||||||
msg[2] = notevalue[chan][data];
|
msg[2] = notevalue[portno][chan][data];
|
||||||
} else if (mod) {
|
} else if (mod) {
|
||||||
int q = swap?val%mod:val/mod, r = swap?val/mod:val%mod;
|
int q = swap?val%mod:val/mod, r = swap?val/mod:val%mod;
|
||||||
int d = msg[1] + datavals(q, mod_step, mod_steps, mod_n_steps);
|
int d = msg[1] + datavals(q, mod_step, mod_steps, mod_n_steps);
|
||||||
|
@ -155,15 +158,15 @@ send_midi(uint8_t portno, int status, int data,
|
||||||
if (!step) step = 1;
|
if (!step) step = 1;
|
||||||
dir *= step;
|
dir *= step;
|
||||||
if (dir > 0) {
|
if (dir > 0) {
|
||||||
if (ccvalue[chan][data] >= 127) return;
|
if (ccvalue[portno][chan][data] >= 127) return;
|
||||||
ccvalue[chan][data] += dir;
|
ccvalue[portno][chan][data] += dir;
|
||||||
if (ccvalue[chan][data] > 127) ccvalue[chan][data] = 127;
|
if (ccvalue[portno][chan][data] > 127) ccvalue[portno][chan][data] = 127;
|
||||||
} else {
|
} else {
|
||||||
if (ccvalue[chan][data] == 0) return;
|
if (ccvalue[portno][chan][data] == 0) return;
|
||||||
ccvalue[chan][data] += dir;
|
ccvalue[portno][chan][data] += dir;
|
||||||
if (ccvalue[chan][data] < 0) ccvalue[chan][data] = 0;
|
if (ccvalue[portno][chan][data] < 0) ccvalue[portno][chan][data] = 0;
|
||||||
}
|
}
|
||||||
msg[2] = ccvalue[chan][data];
|
msg[2] = ccvalue[portno][chan][data];
|
||||||
}
|
}
|
||||||
} else if (mod) {
|
} else if (mod) {
|
||||||
int q = swap?val%mod:val/mod, r = swap?val/mod:val%mod;
|
int q = swap?val%mod:val/mod, r = swap?val/mod:val%mod;
|
||||||
|
@ -186,15 +189,15 @@ send_midi(uint8_t portno, int status, int data,
|
||||||
if (!step) step = 1;
|
if (!step) step = 1;
|
||||||
dir *= step;
|
dir *= step;
|
||||||
if (dir > 0) {
|
if (dir > 0) {
|
||||||
if (kpvalue[chan][data] >= 127) return;
|
if (kpvalue[portno][chan][data] >= 127) return;
|
||||||
kpvalue[chan][data] += dir;
|
kpvalue[portno][chan][data] += dir;
|
||||||
if (kpvalue[chan][data] > 127) kpvalue[chan][data] = 127;
|
if (kpvalue[portno][chan][data] > 127) kpvalue[portno][chan][data] = 127;
|
||||||
} else {
|
} else {
|
||||||
if (kpvalue[chan][data] == 0) return;
|
if (kpvalue[portno][chan][data] == 0) return;
|
||||||
kpvalue[chan][data] += dir;
|
kpvalue[portno][chan][data] += dir;
|
||||||
if (kpvalue[chan][data] < 0) kpvalue[chan][data] = 0;
|
if (kpvalue[portno][chan][data] < 0) kpvalue[portno][chan][data] = 0;
|
||||||
}
|
}
|
||||||
msg[2] = kpvalue[chan][data];
|
msg[2] = kpvalue[portno][chan][data];
|
||||||
} else if (mod) {
|
} else if (mod) {
|
||||||
int q = swap?val%mod:val/mod, r = swap?val/mod:val%mod;
|
int q = swap?val%mod:val/mod, r = swap?val/mod:val%mod;
|
||||||
int d = msg[1] + datavals(q, mod_step, mod_steps, mod_n_steps);
|
int d = msg[1] + datavals(q, mod_step, mod_steps, mod_n_steps);
|
||||||
|
@ -216,15 +219,15 @@ send_midi(uint8_t portno, int status, int data,
|
||||||
if (!step) step = 1;
|
if (!step) step = 1;
|
||||||
dir *= step;
|
dir *= step;
|
||||||
if (dir > 0) {
|
if (dir > 0) {
|
||||||
if (cpvalue[chan] >= 127) return;
|
if (cpvalue[portno][chan] >= 127) return;
|
||||||
cpvalue[chan] += dir;
|
cpvalue[portno][chan] += dir;
|
||||||
if (cpvalue[chan] > 127) cpvalue[chan] = 127;
|
if (cpvalue[portno][chan] > 127) cpvalue[portno][chan] = 127;
|
||||||
} else {
|
} else {
|
||||||
if (cpvalue[chan] == 0) return;
|
if (cpvalue[portno][chan] == 0) return;
|
||||||
cpvalue[chan] += dir;
|
cpvalue[portno][chan] += dir;
|
||||||
if (cpvalue[chan] < 0) cpvalue[chan] = 0;
|
if (cpvalue[portno][chan] < 0) cpvalue[portno][chan] = 0;
|
||||||
}
|
}
|
||||||
msg[1] = cpvalue[chan];
|
msg[1] = cpvalue[portno][chan];
|
||||||
} else if (mod) {
|
} else if (mod) {
|
||||||
int v = datavals(swap?val/mod:val%mod, step, steps, n_steps);
|
int v = datavals(swap?val/mod:val%mod, step, steps, n_steps);
|
||||||
if (v > 127 || v < 0) return;
|
if (v > 127 || v < 0) return;
|
||||||
|
@ -243,15 +246,15 @@ send_midi(uint8_t portno, int status, int data,
|
||||||
if (!step) step = 1;
|
if (!step) step = 1;
|
||||||
dir *= step;
|
dir *= step;
|
||||||
if (dir > 0) {
|
if (dir > 0) {
|
||||||
if (pbvalue[chan] >= 16383) return;
|
if (pbvalue[portno][chan] >= 16383) return;
|
||||||
pbvalue[chan] += dir;
|
pbvalue[portno][chan] += dir;
|
||||||
if (pbvalue[chan] > 16383) pbvalue[chan] = 16383;
|
if (pbvalue[portno][chan] > 16383) pbvalue[portno][chan] = 16383;
|
||||||
} else {
|
} else {
|
||||||
if (pbvalue[chan] == 0) return;
|
if (pbvalue[portno][chan] == 0) return;
|
||||||
pbvalue[chan] += dir;
|
pbvalue[portno][chan] += dir;
|
||||||
if (pbvalue[chan] < 0) pbvalue[chan] = 0;
|
if (pbvalue[portno][chan] < 0) pbvalue[portno][chan] = 0;
|
||||||
}
|
}
|
||||||
pbval = pbvalue[chan];
|
pbval = pbvalue[portno][chan];
|
||||||
} else if (mod) {
|
} else if (mod) {
|
||||||
int v = datavals(swap?val/mod:val%mod, step, steps, n_steps);
|
int v = datavals(swap?val/mod:val%mod, step, steps, n_steps);
|
||||||
if (v > 16383 || v < 0) return;
|
if (v > 16383 || v < 0) return;
|
||||||
|
@ -280,6 +283,7 @@ send_midi(uint8_t portno, int status, int data,
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (ret_msg) memcpy(ret_msg, msg, 3);
|
||||||
if (!recursive)
|
if (!recursive)
|
||||||
queue_midi(&seq, msg, portno);
|
queue_midi(&seq, msg, portno);
|
||||||
else
|
else
|
||||||
|
@ -726,6 +730,29 @@ static void end_debug()
|
||||||
// maximum recursion depth
|
// maximum recursion depth
|
||||||
#define MAX_DEPTH 32
|
#define MAX_DEPTH 32
|
||||||
|
|
||||||
|
// shift feedback
|
||||||
|
uint8_t shift_fb[N_SHIFTS][3];
|
||||||
|
|
||||||
|
static int toggle_msg(uint8_t msg[3])
|
||||||
|
{
|
||||||
|
if (msg[0] < 0x80) return 0;
|
||||||
|
switch (msg[0]&0xf0) {
|
||||||
|
case 0xc0:
|
||||||
|
return 0;
|
||||||
|
case 0xd0:
|
||||||
|
msg[1] = 0;
|
||||||
|
break;
|
||||||
|
case 0xe0:
|
||||||
|
msg[1] = 0x40;
|
||||||
|
msg[2] = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
msg[2] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
send_strokes(translation *tr, uint8_t portno, int status, int chan,
|
send_strokes(translation *tr, uint8_t portno, int status, int chan,
|
||||||
int data, int data2, int index, int dir, int depth)
|
int data, int data2, int index, int dir, int depth)
|
||||||
|
@ -788,9 +815,15 @@ send_strokes(translation *tr, uint8_t portno, int status, int chan,
|
||||||
nkeys++;
|
nkeys++;
|
||||||
} else if (s->shift) {
|
} else if (s->shift) {
|
||||||
// toggle shift status
|
// toggle shift status
|
||||||
if (shift != s->shift)
|
if (shift != s->shift) {
|
||||||
|
if (shift) {
|
||||||
|
// reset current shift feedback
|
||||||
|
if (toggle_msg(shift_fb[shift-1]))
|
||||||
|
queue_midi(&seq, shift_fb[shift-1], 1);
|
||||||
|
memset(shift_fb[shift-1], 0, 3);
|
||||||
|
}
|
||||||
shift = s->shift;
|
shift = s->shift;
|
||||||
else
|
} else
|
||||||
shift = 0;
|
shift = 0;
|
||||||
} else if (!s->status) {
|
} else if (!s->status) {
|
||||||
// do nothing (NOP)
|
// do nothing (NOP)
|
||||||
|
@ -804,10 +837,26 @@ send_strokes(translation *tr, uint8_t portno, int status, int chan,
|
||||||
else
|
else
|
||||||
fprintf(stderr, "Error: $%s: recursion too deep\n",
|
fprintf(stderr, "Error: $%s: recursion too deep\n",
|
||||||
debug_key(tr, name, status, chan, data, dir));
|
debug_key(tr, name, status, chan, data, dir));
|
||||||
|
} else if (s->feedback) {
|
||||||
|
if (!s->recursive && jack_num_outputs > 1) {
|
||||||
|
if (s->feedback == 1)
|
||||||
|
// direct feedback, simply flip the port number
|
||||||
|
send_midi(!portno,
|
||||||
|
s->status, s->data, s->step, s->n_steps, s->steps,
|
||||||
|
s->incr, index, dir, mod,
|
||||||
|
step, n_steps, steps, data2, s->swap, 0, depth, 0);
|
||||||
|
else if (portno == 0 && !mod && !dir)
|
||||||
|
// shift feedback, this only works with key translations right
|
||||||
|
// now, and portno *must* be zero
|
||||||
|
send_midi(1, s->status, s->data, s->step, s->n_steps, s->steps,
|
||||||
|
s->incr, !shift, 0, 0,
|
||||||
|
step, n_steps, steps, data2, s->swap, 0, depth,
|
||||||
|
shift?shift_fb[shift-1]:0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
send_midi(portno, s->status, s->data, s->step, s->n_steps, s->steps,
|
send_midi(portno, s->status, s->data, s->step, s->n_steps, s->steps,
|
||||||
s->incr, index, dir, mod,
|
s->incr, index, dir, mod,
|
||||||
step, n_steps, steps, data2, s->swap, s->recursive, depth);
|
step, n_steps, steps, data2, s->swap, s->recursive, depth, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s = s->next;
|
s = s->next;
|
||||||
|
@ -1276,7 +1325,7 @@ handle_event(uint8_t *msg, uint8_t portno, int depth, int recursive)
|
||||||
end_debug();
|
end_debug();
|
||||||
break;
|
break;
|
||||||
case 0xb0:
|
case 0xb0:
|
||||||
if (direct_feedback && portno) ccvalue[chan][msg[1]] = msg[2];
|
if (auto_feedback) ccvalue[!portno][chan][msg[1]] = msg[2];
|
||||||
start_debug();
|
start_debug();
|
||||||
if (get_cc_mod(tr, portno, chan, msg[1])) {
|
if (get_cc_mod(tr, portno, chan, msg[1])) {
|
||||||
send_strokes(tr, portno, status, chan, msg[1], msg[2], 0, 0, depth);
|
send_strokes(tr, portno, status, chan, msg[1], msg[2], 0, 0, depth);
|
||||||
|
@ -1344,7 +1393,7 @@ handle_event(uint8_t *msg, uint8_t portno, int depth, int recursive)
|
||||||
end_debug();
|
end_debug();
|
||||||
break;
|
break;
|
||||||
case 0x90:
|
case 0x90:
|
||||||
if (direct_feedback && portno) notevalue[chan][msg[1]] = msg[2];
|
if (auto_feedback) notevalue[!portno][chan][msg[1]] = msg[2];
|
||||||
start_debug();
|
start_debug();
|
||||||
if (get_note_mod(tr, portno, chan, msg[1])) {
|
if (get_note_mod(tr, portno, chan, msg[1])) {
|
||||||
send_strokes(tr, portno, status, chan, msg[1], msg[2], 0, 0, depth);
|
send_strokes(tr, portno, status, chan, msg[1], msg[2], 0, 0, depth);
|
||||||
|
@ -1381,7 +1430,7 @@ handle_event(uint8_t *msg, uint8_t portno, int depth, int recursive)
|
||||||
end_debug();
|
end_debug();
|
||||||
break;
|
break;
|
||||||
case 0xa0:
|
case 0xa0:
|
||||||
if (direct_feedback && portno) kpvalue[chan][msg[1]] = msg[2];
|
if (auto_feedback) kpvalue[!portno][chan][msg[1]] = msg[2];
|
||||||
start_debug();
|
start_debug();
|
||||||
if (get_kp_mod(tr, portno, chan, msg[1])) {
|
if (get_kp_mod(tr, portno, chan, msg[1])) {
|
||||||
send_strokes(tr, portno, status, chan, msg[1], msg[2], 0, 0, depth);
|
send_strokes(tr, portno, status, chan, msg[1], msg[2], 0, 0, depth);
|
||||||
|
@ -1418,7 +1467,7 @@ handle_event(uint8_t *msg, uint8_t portno, int depth, int recursive)
|
||||||
end_debug();
|
end_debug();
|
||||||
break;
|
break;
|
||||||
case 0xd0:
|
case 0xd0:
|
||||||
if (direct_feedback && portno) cpvalue[chan] = msg[1];
|
if (auto_feedback) cpvalue[!portno][chan] = msg[1];
|
||||||
start_debug();
|
start_debug();
|
||||||
if (get_cp_mod(tr, portno, chan)) {
|
if (get_cp_mod(tr, portno, chan)) {
|
||||||
send_strokes(tr, portno, status, chan, 0, msg[1], 0, 0, depth);
|
send_strokes(tr, portno, status, chan, 0, msg[1], 0, 0, depth);
|
||||||
|
@ -1456,7 +1505,7 @@ handle_event(uint8_t *msg, uint8_t portno, int depth, int recursive)
|
||||||
break;
|
break;
|
||||||
case 0xe0: {
|
case 0xe0: {
|
||||||
int bend = ((msg[2] << 7) | msg[1]) - 8192;
|
int bend = ((msg[2] << 7) | msg[1]) - 8192;
|
||||||
if (direct_feedback && portno) pbvalue[chan] = bend+8192;
|
if (auto_feedback) pbvalue[!portno][chan] = bend+8192;
|
||||||
start_debug();
|
start_debug();
|
||||||
if (get_pb_mod(tr, portno, chan)) {
|
if (get_pb_mod(tr, portno, chan)) {
|
||||||
send_strokes(tr, portno, status, chan, 0, bend+8192, 0, 0, depth);
|
send_strokes(tr, portno, status, chan, 0, bend+8192, 0, 0, depth);
|
||||||
|
@ -1597,7 +1646,7 @@ main(int argc, char **argv)
|
||||||
add_command("-k", 1);
|
add_command("-k", 1);
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
direct_feedback = 0;
|
auto_feedback = 0;
|
||||||
add_command("-n", 1);
|
add_command("-n", 1);
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
|
|
|
@ -65,6 +65,9 @@ typedef struct _stroke {
|
||||||
// the recursive bit indicates a MIDI message which is to be translated
|
// the recursive bit indicates a MIDI message which is to be translated
|
||||||
// recursively
|
// recursively
|
||||||
uint8_t recursive;
|
uint8_t recursive;
|
||||||
|
// the feedback bit indicates a MIDI message which is to be sent back to
|
||||||
|
// device or application (flipping the output port)
|
||||||
|
uint8_t feedback;
|
||||||
// the dirty bit indicates a MIDI event for which a release event still
|
// the dirty bit indicates a MIDI event for which a release event still
|
||||||
// needs to be generated in key events
|
// needs to be generated in key events
|
||||||
uint8_t dirty;
|
uint8_t dirty;
|
||||||
|
@ -124,6 +127,6 @@ extern int debug_regex, debug_strokes, debug_keys, debug_midi;
|
||||||
extern int default_debug_regex, default_debug_strokes, default_debug_keys,
|
extern int default_debug_regex, default_debug_strokes, default_debug_keys,
|
||||||
default_debug_midi;
|
default_debug_midi;
|
||||||
extern char *config_file_name;
|
extern char *config_file_name;
|
||||||
extern int jack_num_outputs, system_passthrough, direct_feedback;
|
extern int jack_num_outputs, system_passthrough, auto_feedback;
|
||||||
extern int midi_octave, shift;
|
extern int midi_octave, shift;
|
||||||
extern char *jack_client_name;
|
extern char *jack_client_name;
|
||||||
|
|
24
readconfig.c
24
readconfig.c
|
@ -633,6 +633,7 @@ print_stroke(stroke *s, int mod, int step, int n_steps, int *steps, int val)
|
||||||
int channel = (s->status & 0x0f) + 1;
|
int channel = (s->status & 0x0f) + 1;
|
||||||
char *suffix = s->swap?"'":s->incr?"~":"";
|
char *suffix = s->swap?"'":s->incr?"~":"";
|
||||||
if (s->recursive) printf("$");
|
if (s->recursive) printf("$");
|
||||||
|
if (s->feedback) printf(s->feedback==2?"^":"!");
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 0x90:
|
case 0x90:
|
||||||
if (mod) {
|
if (mod) {
|
||||||
|
@ -815,7 +816,7 @@ append_nop(void)
|
||||||
|
|
||||||
void
|
void
|
||||||
append_midi(int status, int data, int step, int n_steps, int *steps,
|
append_midi(int status, int data, int step, int n_steps, int *steps,
|
||||||
int swap, int incr, int recursive)
|
int swap, int incr, int recursive, int feedback)
|
||||||
{
|
{
|
||||||
stroke *s = (stroke *)allocate(sizeof(stroke));
|
stroke *s = (stroke *)allocate(sizeof(stroke));
|
||||||
|
|
||||||
|
@ -828,6 +829,7 @@ append_midi(int status, int data, int step, int n_steps, int *steps,
|
||||||
s->steps = stepsdup(n_steps, steps);
|
s->steps = stepsdup(n_steps, steps);
|
||||||
s->incr = incr;
|
s->incr = incr;
|
||||||
s->recursive = recursive;
|
s->recursive = recursive;
|
||||||
|
s->feedback = feedback;
|
||||||
// if this is a keystroke event, for all messages but program change (which
|
// if this is a keystroke event, for all messages but program change (which
|
||||||
// has no "on" and "off" states), mark the event as "dirty" so that the
|
// has no "on" and "off" states), mark the event as "dirty" so that the
|
||||||
// corresponding "off" event gets added later to the "release" strokes
|
// corresponding "off" event gets added later to the "release" strokes
|
||||||
|
@ -1588,7 +1590,7 @@ add_release(int all_keys)
|
||||||
if (!s->keysym && !s->shift && s->dirty) {
|
if (!s->keysym && !s->shift && s->dirty) {
|
||||||
append_midi(s->status, s->data,
|
append_midi(s->status, s->data,
|
||||||
s->step, s->n_steps, s->steps,
|
s->step, s->n_steps, s->steps,
|
||||||
s->swap, s->incr, s->recursive);
|
s->swap, s->incr, s->recursive, s->feedback);
|
||||||
s->dirty = 0;
|
s->dirty = 0;
|
||||||
}
|
}
|
||||||
s = s->next;
|
s = s->next;
|
||||||
|
@ -1613,7 +1615,7 @@ add_release(int all_keys)
|
||||||
} else {
|
} else {
|
||||||
append_midi(s->status, s->data,
|
append_midi(s->status, s->data,
|
||||||
s->step, s->n_steps, s->steps,
|
s->step, s->n_steps, s->steps,
|
||||||
s->swap, s->incr, s->recursive);
|
s->swap, s->incr, s->recursive, s->feedback);
|
||||||
}
|
}
|
||||||
s = s->next;
|
s = s->next;
|
||||||
}
|
}
|
||||||
|
@ -1633,7 +1635,7 @@ add_release(int all_keys)
|
||||||
} else {
|
} else {
|
||||||
append_midi(s->status, s->data,
|
append_midi(s->status, s->data,
|
||||||
s->step, s->n_steps, s->steps,
|
s->step, s->n_steps, s->steps,
|
||||||
s->swap, s->incr, s->recursive);
|
s->swap, s->incr, s->recursive, s->feedback);
|
||||||
}
|
}
|
||||||
s = s->next;
|
s = s->next;
|
||||||
}
|
}
|
||||||
|
@ -1652,7 +1654,7 @@ add_release(int all_keys)
|
||||||
} else {
|
} else {
|
||||||
append_midi(s->status, s->data,
|
append_midi(s->status, s->data,
|
||||||
s->step, s->n_steps, s->steps,
|
s->step, s->n_steps, s->steps,
|
||||||
s->swap, s->incr, s->recursive);
|
s->swap, s->incr, s->recursive, s->feedback);
|
||||||
}
|
}
|
||||||
s = s->next;
|
s = s->next;
|
||||||
}
|
}
|
||||||
|
@ -1693,9 +1695,13 @@ void
|
||||||
add_midi(char *tok)
|
add_midi(char *tok)
|
||||||
{
|
{
|
||||||
int status, data, step, n_steps, *steps, incr, dir = 0, mod = 0, swap = 0;
|
int status, data, step, n_steps, *steps, incr, dir = 0, mod = 0, swap = 0;
|
||||||
int recursive = *tok == '$';
|
int recursive = *tok == '$', fb = *tok == '!', fb2 = *tok == '^';
|
||||||
char buf[100];
|
char buf[100];
|
||||||
if (parse_midi(tok+recursive, buf, 0, mode, &status, &data, &step, &n_steps, &steps, &incr, &dir, &mod, &swap)) {
|
if (fb2 && mode != 1) {
|
||||||
|
fprintf(stderr, "shift feedback only allowed in key translations: %s\n", tok);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (parse_midi(tok+recursive+fb+fb2, buf, 0, mode, &status, &data, &step, &n_steps, &steps, &incr, &dir, &mod, &swap)) {
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
// 'ch' token; this doesn't actually generate any output, it just sets
|
// 'ch' token; this doesn't actually generate any output, it just sets
|
||||||
// the default MIDI channel
|
// the default MIDI channel
|
||||||
|
@ -1704,7 +1710,7 @@ add_midi(char *tok)
|
||||||
fprintf(stderr, "invalid macro call: %s\n", tok);
|
fprintf(stderr, "invalid macro call: %s\n", tok);
|
||||||
} else {
|
} else {
|
||||||
append_midi(status, data, step, n_steps, steps,
|
append_midi(status, data, step, n_steps, steps,
|
||||||
swap, incr!=0, recursive);
|
swap, incr!=0, recursive, fb2?2:fb);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// inspect the token that was actually recognized (if any) to give some
|
// inspect the token that was actually recognized (if any) to give some
|
||||||
|
@ -1866,7 +1872,7 @@ read_config_file(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(tok, "NO_FEEDBACK")) {
|
if (!strcmp(tok, "NO_FEEDBACK")) {
|
||||||
direct_feedback = 0; // -n
|
auto_feedback = 0; // -n
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(tok, "SYSTEM_PASSTHROUGH")) {
|
if (!strcmp(tok, "SYSTEM_PASSTHROUGH")) {
|
||||||
|
|
Loading…
Reference in New Issue