Skip to content

Commit

Permalink
Fix stuck keys, add KeyStep
Browse files Browse the repository at this point in the history
  • Loading branch information
HackerFoo committed Feb 23, 2021
1 parent 85b5204 commit 4654ce1
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 47 deletions.
60 changes: 31 additions & 29 deletions midi_tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static_assert(MIDI_TASKS_COUNT <= 64, "too many tasks");
DTASK_GROUP(midi_tasks)

// passthrough
DTASK(midi_in, struct { int id; seg_t msg; }) {
DTASK(midi_in, struct { int id; unsigned char status; seg_t data; }) {
return true;
}

Expand Down Expand Up @@ -108,12 +108,14 @@ DTASK(beat, struct { unsigned int then, now; }) {
}

DTASK(print_midi_msg, bool) {
const seg_t *msg = &DREF(midi_in)->msg;
printf("%d > 0x%x:", DREF(midi_in)->id, (unsigned char)msg->s[0]);
RANGEUP(i, 1, msg->n) {
printf(" %d", (unsigned char)msg->s[i]);
const midi_in_t *msg = DREF(midi_in);
if(msg->status != 0xf8) {
printf("%d > 0x%x:", msg->id, msg->status);
COUNTUP(i, msg->data.n) {
printf(" %d", (unsigned char)msg->data.s[i]);
}
printf("\n");
}
printf("\n");
return true;
}

Expand All @@ -126,15 +128,15 @@ void set_bit(uint64_t *s, int k, bool v) {
}

DTASK(pad, key_event_t) {
if(DREF(midi_in)->id != 0) return false;
const seg_t *msg_in = &DREF(midi_in)->msg;
unsigned char control = msg_in->s[0] & 0xf0;
const midi_in_t *msg = DREF(midi_in);
if(msg->id != 0) return false;
unsigned char control = msg->status & 0xf0;
if(ONEOF(control, 0x80, 0x90)) {
int p = msg_in->s[1] - 36;
int p = msg->data.s[0] - 36;
if(INRANGE(p, 0, 63)) {
*DREF(pad) = (key_event_t) {
.id = p,
.velocity = (control == 0x90 ? 1 : -1) * (int16_t)msg_in->s[2]
.velocity = (control == 0x90 ? 1 : -1) * (int16_t)msg->data.s[1]
};
return true;
}
Expand All @@ -143,48 +145,48 @@ DTASK(pad, key_event_t) {
}

DTASK(external_key, key_event_t) {
if(DREF(midi_in)->id == 0) return false;
const seg_t *msg_in = &DREF(midi_in)->msg;
unsigned char control = msg_in->s[0] & 0xf0;
const midi_in_t *msg = DREF(midi_in);
if(msg->id == 0) return false;
unsigned char control = msg->status & 0xf0;
if(ONEOF(control, 0x80, 0x90)) {
*DREF(external_key) = (external_key_t) {
.id = msg_in->s[1],
.velocity = (control == 0x90 ? 1 : -1) * (int16_t)msg_in->s[2]
.id = msg->data.s[0],
.velocity = (control == 0x90 ? 1 : -1) * (int16_t)msg->data.s[1]
};
return true;
}
return false;
}

DTASK(channel_pressure, int) {
if(DREF(midi_in)->id != 0) return false;
const seg_t *msg_in = &DREF(midi_in)->msg;
unsigned char control = msg_in->s[0] & 0xf0;
const midi_in_t *msg = DREF(midi_in);
if(msg->id != 0) return false;
unsigned char control = msg->status & 0xf0;
if(control == 0xd0) {
*DREF(channel_pressure) = msg_in->s[1];
*DREF(channel_pressure) = msg->data.s[0];
return true;
}
return false;
}

DTASK(pitch_bend, int) {
if(DREF(midi_in)->id != 0) return false;
const seg_t *msg_in = &DREF(midi_in)->msg;
unsigned char control = msg_in->s[0] & 0xf0;
const midi_in_t *msg = DREF(midi_in);
if(msg->id != 0) return false;
unsigned char control = msg->status & 0xf0;
if(control == 0xe0) {
*DREF(pitch_bend) = (msg_in->s[1] & 0x7f) | (((int)msg_in->s[2] & 0x7f) << 7) ;
*DREF(pitch_bend) = (msg->data.s[0] & 0x7f) | (((int)msg->data.s[1] & 0x7f) << 7) ;
return true;
}
return false;
}

DTASK(control_change, struct { int control, value; } ) {
if(DREF(midi_in)->id != 0) return false;
const seg_t *msg_in = &DREF(midi_in)->msg;
unsigned char control = msg_in->s[0] & 0xf0;
const midi_in_t *msg = DREF(midi_in);
if(msg->id != 0) return false;
unsigned char control = msg->status & 0xf0;
if(control == 0xb0) {
DREF(control_change)->control = msg_in->s[1];
DREF(control_change)->value = msg_in->s[2];
DREF(control_change)->control = msg->data.s[0];
DREF(control_change)->value = msg->data.s[1];
return true;
}
return false;
Expand Down
36 changes: 18 additions & 18 deletions midipush.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ STATIC_ALLOC_DEPENDENT(ext_rb, char, sizeof(ring_buffer_t) + static_sizeof(midi_
int fixed_length(unsigned char c) {
int
l = (c >> 4) & 7, // left 3 bits
r = (c & 7); // right 4 bits
r = (c & 0x0f); // right 4 bits

if(l != 7) {
return (l & 6) == 4 ? 2 : 3; // channel voice messages
Expand All @@ -195,25 +195,26 @@ int fixed_length(unsigned char c) {
}
}

seg_t find_midi_msg(const char **s, const char *e) {

// skip to first control byte
seg_t find_midi_msg(unsigned char *status, const char **s, const char *e) {
const char *p = *s;
while(p < e &&
!((unsigned char)*p & 0x80)) {
printf("* 0x%x\n", *p);
p++;
if(!*status) {
// skip to first control byte
while(p < e &&
!((unsigned char)*p & 0x80)) {
printf("* 0x%x\n", *p);
p++;
}
}
if(p == e) {
*s = e;
return (seg_t) {0};
}
if((unsigned char)*p & 0x80) {
*status = *p++;
}
seg_t msg = { .s = p, .n = 0 };

int len = fixed_length(*p);
int len = fixed_length(*status);
if(len < 0) { // sysex
p++;
msg.n++;
while(p < e) {
msg.n++;
if((unsigned char)*p == 0xf7) {
Expand All @@ -224,7 +225,7 @@ seg_t find_midi_msg(const char **s, const char *e) {
}
return (seg_t) {0};
} else {
msg.n = len;
msg.n = len - 1;
}

if(e - p < msg.n) {
Expand All @@ -241,7 +242,6 @@ bool read_midi_msgs(struct midi *m, midi_tasks_state_t *state, dtask_set_t *even
while(success) {

// read from ring buffer first
midi_input_buffer[0] = m->last_status;
char *buffer = midi_input_buffer + 1;
size_t remaining = static_sizeof(midi_input_buffer) - 1;
ssize_t n = rb_read(m->rb, buffer, remaining);
Expand All @@ -261,12 +261,12 @@ bool read_midi_msgs(struct midi *m, midi_tasks_state_t *state, dtask_set_t *even
}

const char *buffer_end = buffer + n;
if(!((unsigned char)buffer[0] & 0x80)) buffer--;
seg_t msg;
while(msg = find_midi_msg(&buffer, buffer_end), msg.n) {
m->last_status = msg.s[0];
while(msg = find_midi_msg(&m->last_status, &buffer, buffer_end), msg.n) {
midi_state.midi_in.status = m->last_status;
if(!msg.n) m->last_status = 0; // ***
midi_state.midi_in.id = m->id;
midi_state.midi_in.msg = msg;
midi_state.midi_in.data = msg;
*events |= dtask_run((dtask_state_t *)state, MIDI_IN);
if(midi_state.poweroff) {
success = false;
Expand Down
3 changes: 3 additions & 0 deletions run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set -euo pipefail
VIRTUAL_NAME="Virtual Raw"
SYNTH_NAME="Waldorf Kyra"
ADAPTER_NAME="UM-1"
ADAPTER2_NAME="KeyStep"

sudo modprobe snd_virmidi

Expand All @@ -16,10 +17,12 @@ connect_midi() {
virtual=$(get_midi_port "${VIRTUAL_NAME}")
synth=$(get_midi_port "${SYNTH_NAME}")
adapter=$(get_midi_port "${ADAPTER_NAME}")
adapter2=$(get_midi_port "${ADAPTER2_NAME}")
if [ -n "$virtual" ] && [ -n "$synth" ]; then
aconnect -x
aconnect ${virtual} ${synth}
aconnect ${adapter} $((${virtual} + 1)) || true # don't fail
aconnect ${adapter2} $((${virtual} + 1)) || true # don't fail
return 0
else
return -1
Expand Down

0 comments on commit 4654ce1

Please sign in to comment.