tty2midi

serial to midi converter
Log | Files | Refs | README | LICENSE

commit c5700508eaba3129491e5fa1491d84bab89e931f
Author: prenev <an2qzavok@gmail.com>
Date:   Sun, 12 Sep 2021 00:17:54 +0300

commit all the codes

Diffstat:
ALICENSE | 13+++++++++++++
AMakefile | 31+++++++++++++++++++++++++++++++
AREADME | 3+++
Aconfig.mk | 12++++++++++++
Atty2midi.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 145 insertions(+), 0 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2021 Pavel Renev <an2qzavok@gmail.com> + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile @@ -0,0 +1,31 @@ +include config.mk + +SRC = tty2midi.c +OBJ = ${SRC:.c=.o} + +all: tty2midi + +.c.o: + ${CC} -c ${CFLAGS} $< + +${OBJ}: + +tty2midi: ${OBJ} + ${CC} -o $@ ${OBJ} ${LDFLAGS} + +install: all + mkdir -p ${DESTDIR}${PREFIX}/bin/ + cp -f pcmprint $(DESTDIR)${PREFIX}/bin/ + chmod 755 ${DESTDIR}${PREFIX}/bin/pcmprint + mkdir -p ${DESTDIR}${MANPREFIX}/man1 + cp -f pcmprint.1 ${DESTDIR}${MANPREFIX}/man1/pcmprint.1 + chmod 644 ${DESTDIR}${MANPREFIX}/man1/pcmprint.1 + +uninstall: + rm -f ${DESTDIR}${PREFIX}/bin/pcmprint\ + ${DESTDIR}${MANDIR}/pcmprint.1 + +clean: + rm -f tty2midi ${OBJ} + +.PHONY: all clean instal uninstall diff --git a/README b/README @@ -0,0 +1,3 @@ +Recieves messages from a serial port and sends them to ALSA MIDI. +Useful for imlementing musical controllers with something like Arduino. +Paths and tty config are hard-coded because I couldn't be bothered. diff --git a/config.mk b/config.mk @@ -0,0 +1,12 @@ +PREFIX = /usr/local +MANPREFIX = ${PREFIX}/share/man + +INCS = +LIBS = -lasound + +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L +CFLAGS = -g -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} +LDFLAGS = ${LIBS} + +CC = cc + diff --git a/tty2midi.c b/tty2midi.c @@ -0,0 +1,86 @@ +#include<stdio.h> +#include<stdlib.h> +#include<fcntl.h> +#include<unistd.h> +#include<termio.h> +#include<alsa/asoundlib.h> + +int +main(void) +{ + int tf, portid; + struct termios tty; + snd_seq_t *seq; + snd_seq_event_t ev; + snd_midi_event_t *midi; + + /* serial setup */ + tf = open("/dev/ttyACM0", O_RDWR); + if (tf < 0) { + fprintf(stderr, "can't open\n"); + exit(-1); + } + if (tcgetattr(tf, &tty) != 0) { + fprintf(stderr, "tcgetattr failed\n"); + exit(-1); + } + if (cfsetspeed(&tty, B115200) != 0) { + fprintf(stderr, "cfsetspeed failed\n"); + exit(-1); + } + tty.c_cflag &= ~(PARENB|CSTOPB|CSIZE|CRTSCTS); + tty.c_cflag |= CS8|CREAD|CLOCAL; + tty.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHONL|ISIG); + tty.c_iflag &= ~(IXON |IXOFF| IXANY|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); + tty.c_oflag &= ~(OPOST|ONLCR); + tty.c_cc[VTIME] = 0; + tty.c_cc[VMIN] = 1; + tcsetattr(tf, TCSANOW, &tty); + + /* ALSA MIDI setup */ + if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_OUTPUT, 0) != 0) exit(-1); + if (snd_seq_set_client_name(seq, "tty2midi") != 0) { + fprintf(stderr, "set client name failed\n"); + exit(-1); + } + portid = snd_seq_create_simple_port( + seq, + "tty2midi out", + SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, + SND_SEQ_PORT_TYPE_APPLICATION + ); + if (portid < 0) { + fprintf(stderr, "create simple port failed\n"); + exit(-1); + } + if (snd_midi_event_new(16, &midi) != 0) { + fprintf(stderr, "midi event new failed\n"); + exit(-1); + } + while(1) { + unsigned char buf[1024]; + int n, r; + /* TODO: add poll(2) */ + if ((n = read(tf, buf, 1)) == 0) continue; + + //fprintf(stderr, "%x %x %x\t", buf[0], + // buf[1], buf[2]); + + snd_seq_ev_clear(&ev); + snd_seq_ev_set_subs(&ev); + snd_seq_ev_set_direct(&ev); + snd_seq_ev_set_source(&ev, portid); + + r = snd_midi_event_encode_byte(midi, *buf, &ev); + if (r < 0) { + fprintf(stderr, "event encode failed\n"); + } + if (r != 1) continue; + + r = snd_seq_event_output_direct(seq, &ev); + if (r < 0) { + fprintf(stderr, "event output failed: %s\n", snd_strerror(r)); + } + } + return 0; +}