Skip to content

Instantly share code, notes, and snippets.

@pedrolcl
Created January 21, 2019 05:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pedrolcl/295fae736e1a7c6c7253b45817abec4d to your computer and use it in GitHub Desktop.
Save pedrolcl/295fae736e1a7c6c7253b45817abec4d to your computer and use it in GitHub Desktop.
Convert Linux keyboard events into ALSA sequencer events
/*
compile with:
gcc -o input2seq -lasound input2seq.c
*/
#include <linux/input.h>
#include <alsa/asoundlib.h>
#include <fcntl.h>
#include <stdio.h>
//#define INPUT_DEVICE "/dev/input/by-path/platform-i8042-serio-0-event-kbd"
#define INPUT_DEVICE "/dev/input/event2"
#define CHANNEL 0
#define CONTROLLER_SUSTAIN 64
#define CONTROLLER_HOLD2 69
#define CTL_VALUE_ON 127
#define CTL_VALUE_OFF 0
int main(void)
{
struct input_event ie;
int fd, port, err;
snd_seq_t *seq;
snd_seq_event_t ev;
fd = open(INPUT_DEVICE, O_RDONLY);
if (fd == -1) {
perror(INPUT_DEVICE);
return 1;
}
err = snd_seq_open(&seq, "default", SND_SEQ_OPEN_OUTPUT, 0);
if (err < 0) {
fprintf(stderr, "cannot open sequencer: %s\n", snd_strerror(err));
return 1;
}
snd_seq_set_client_name(seq, "Input/MIDI converter");
port = snd_seq_create_simple_port(seq, "Port 1",
SND_SEQ_PORT_CAP_READ |
SND_SEQ_PORT_CAP_SUBS_READ,
SND_SEQ_PORT_TYPE_MIDI_GENERIC |
SND_SEQ_PORT_TYPE_SOFTWARE);
if (port < 0) {
fprintf(stderr, "cannot create port: %s\n", snd_strerror(port));
return 1;
}
snd_seq_ev_clear(&ev);
snd_seq_ev_set_source(&ev, port);
snd_seq_ev_set_subs(&ev);
snd_seq_ev_set_direct(&ev);
for (;;) {
if (read(fd, &ie, sizeof(ie)) != sizeof(ie))
break;
ev.type = SND_SEQ_EVENT_NONE;
if (ie.type == EV_KEY) {
switch (ie.code) {
case KEY_UP:
if (ie.value == 1)
snd_seq_ev_set_controller(&ev, CHANNEL, CONTROLLER_SUSTAIN, CTL_VALUE_ON);
else if (ie.value == 0)
snd_seq_ev_set_controller(&ev, CHANNEL, CONTROLLER_SUSTAIN, CTL_VALUE_OFF);
break;
case KEY_DOWN:
if (ie.value == 1)
snd_seq_ev_set_controller(&ev, CHANNEL, CONTROLLER_HOLD2, CTL_VALUE_ON);
else if (ie.value == 0)
snd_seq_ev_set_controller(&ev, CHANNEL, CONTROLLER_HOLD2, CTL_VALUE_OFF);
break;
}
}
if (ev.type != SND_SEQ_EVENT_NONE)
snd_seq_event_output_direct(seq, &ev);
}
snd_seq_close(seq);
close(fd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment