mirror of
https://github.com/gmcn42/mt32-pi-control.git
synced 2026-09-22 18:37:58 +00:00
Working Linux/ALSA version :)
This commit is contained in:
1 parent
8320a2e6b0
commit
680b3f5e5f
2 files changed
+146
-18
No files matched your search
@@ -230,7 +230,10 @@ int main(int argc, char *argv[]) {
|
||||
return EXIT_SUCCESS;
|
||||
#endif
|
||||
default:
|
||||
mididev_parse_arg(c, optarg);
|
||||
if(mididev_parse_arg(c, optarg)<0) {
|
||||
fprintf(stderr, "Error parsing argument \"%s\"\n", optarg);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -371,6 +374,7 @@ int main(int argc, char *argv[]) {
|
||||
ret = fio_open(&fh, syx_fname, FIO_OPEN_RD);
|
||||
if(ret!=0) {
|
||||
fprintf(stderr, "ERROR: Can't open %s.\n", syx_fname);
|
||||
mididev_deinit();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -392,6 +396,7 @@ int main(int argc, char *argv[]) {
|
||||
if(fbuf[i] == 0xF0) {
|
||||
if(found_start) {
|
||||
fprintf(stderr, "ERROR: Malformed SysEx in %s.\n", syx_fname);
|
||||
mididev_deinit();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
found_start = 1;
|
||||
@@ -401,6 +406,7 @@ int main(int argc, char *argv[]) {
|
||||
if(found_start && fbuf[i] == 0xF7) {
|
||||
if(found_end) {
|
||||
fprintf(stderr, "ERROR: Malformed SysEx in %s.\n", syx_fname);
|
||||
mididev_deinit();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
found_end = 1;
|
||||
@@ -409,6 +415,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
if(!found_start || !found_end) {
|
||||
fprintf(stderr, "ERROR: Malformed or too long SysEx in %s.\n", syx_fname);
|
||||
mididev_deinit();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
mididev_send_bytes(fbuf+start_index, end_index - start_index+1);
|
||||
|
||||
+138
-17
@@ -8,44 +8,165 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
#include "midi_dev.h"
|
||||
|
||||
typedef enum {
|
||||
MIDI_OP_NOTEOFF = 0x80,
|
||||
MIDI_OP_NOTEON = 0x90,
|
||||
MIDI_OP_KEYPRESS = 0xA0,
|
||||
MIDI_OP_CTRL = 0xB0,
|
||||
MIDI_OP_PC = 0xC0,
|
||||
MIDI_OP_CC = 0xD0,
|
||||
MIDI_OP_PB = 0xE0,
|
||||
MIDI_OP_SYX = 0xF0
|
||||
} midi_op_t;
|
||||
|
||||
static snd_seq_t *seq = NULL;
|
||||
static int src_port = -1, dst_port = -1, dst_client = -1;
|
||||
|
||||
static char *dev_optstr = "p:";
|
||||
|
||||
int mididev_init(void) {
|
||||
if(dst_port == -1 || dst_client == -1) {
|
||||
fprintf(stderr, "ERROR: You must specify ALSA client and port using -p [CLIENT]:[PORT]\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(snd_seq_open(&seq, "default", SND_SEQ_OPEN_OUTPUT, 0) < 0) {
|
||||
fprintf(stderr, "ERROR: Could not open ALSA sequencer.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( (src_port = snd_seq_create_simple_port(
|
||||
seq,
|
||||
"mt32-pi-ctl",
|
||||
SND_SEQ_PORT_CAP_READ,
|
||||
SND_SEQ_PORT_TYPE_APPLICATION)) < 0) {
|
||||
fprintf(stderr, "ERROR: Could not create MIDI output.\n");
|
||||
snd_seq_close(seq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(snd_seq_connect_to(seq, src_port, dst_client, dst_port) < 0) {
|
||||
fprintf(stderr, "ERROR: Could not connect to MIDI port %d:%d.\n", dst_client, dst_port);
|
||||
mididev_deinit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mididev_deinit(void) {
|
||||
snd_seq_delete_simple_port(seq, src_port);
|
||||
snd_seq_close(seq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int mididev_send_bytes(const unsigned char *buf, int len) {
|
||||
if(len==0) return 0;
|
||||
if(len==0) return 0;
|
||||
|
||||
snd_seq_event_t ev;
|
||||
snd_seq_ev_clear(&ev);
|
||||
snd_seq_ev_set_direct(&ev);
|
||||
snd_seq_ev_set_source(&ev, src_port);
|
||||
snd_seq_ev_set_dest(&ev, dst_client, dst_port);
|
||||
|
||||
midi_op_t o = (midi_op_t)(buf[0] & 0xF0);
|
||||
|
||||
if((buf[0] == 0xF0 && buf[len-1] == 0xF7) || len==3) {
|
||||
for(int i=0; i<len; i++) {
|
||||
fprintf(stderr, "%02X ", buf[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
} else {
|
||||
fprintf(stderr, "Error: Non-SysEx message with more than 3 bytes.\n");
|
||||
return -1;
|
||||
unsigned char *tempbuf = NULL;
|
||||
|
||||
switch(o) {
|
||||
case MIDI_OP_NOTEOFF:
|
||||
if(len != 3) goto handle_error;
|
||||
snd_seq_ev_set_noteoff(&ev, buf[0]&0x0F, buf[1], buf[2]);
|
||||
break;
|
||||
case MIDI_OP_NOTEON:
|
||||
if(len != 3) goto handle_error;
|
||||
snd_seq_ev_set_noteon(&ev, buf[0]&0x0F, buf[1], buf[2]);
|
||||
break;
|
||||
case MIDI_OP_KEYPRESS:
|
||||
if(len != 3) goto handle_error;
|
||||
snd_seq_ev_set_keypress(&ev, buf[0]&0x0F, buf[1], buf[2]);
|
||||
break;
|
||||
case MIDI_OP_CTRL:
|
||||
if(len != 3) goto handle_error;
|
||||
snd_seq_ev_set_controller(&ev, buf[0]&0x0F, buf[1], buf[2]);
|
||||
break;
|
||||
case MIDI_OP_PC:
|
||||
if(len != 2) goto handle_error;
|
||||
snd_seq_ev_set_pgmchange(&ev, buf[0]&0x0F, buf[1]);
|
||||
break;
|
||||
case MIDI_OP_CC:
|
||||
if(len != 2) goto handle_error;
|
||||
snd_seq_ev_set_chanpress(&ev, buf[0]&0x0F, buf[1]);
|
||||
break;
|
||||
case MIDI_OP_PB:
|
||||
if(len != 3) goto handle_error;
|
||||
unsigned char par = (buf[1] & 0x7F) + ((buf[2] & 0x7F)<<7);
|
||||
snd_seq_ev_set_pitchbend(&ev, buf[0]&0x0F, par);
|
||||
break;
|
||||
case MIDI_OP_SYX:
|
||||
if(buf[len-1] != 0xF7) goto handle_error;
|
||||
{
|
||||
tempbuf = malloc(len);
|
||||
if(tempbuf == NULL) {
|
||||
fprintf(stderr, "ERROR: Memory allocation error.\n");
|
||||
return -1;
|
||||
}
|
||||
memcpy(tempbuf, buf, len);
|
||||
snd_seq_ev_set_sysex(&ev, len, tempbuf);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
handle_error:
|
||||
fprintf(stderr, "ERROR: Unknown MIDI message.\n");
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
//fprintf(stderr, "len:%d end:%02X\n", len, buf[len-1]);
|
||||
// for(int i=0; i<len; i++) {
|
||||
// fprintf(stderr, "%02X ", buf[i]);
|
||||
// }
|
||||
//fprintf(stderr, "\n");
|
||||
snd_seq_event_output(seq, &ev);
|
||||
snd_seq_drain_output(seq);
|
||||
|
||||
if(tempbuf != NULL) free(tempbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mididev_print_usage(void) {}
|
||||
void mididev_print_usage(void) {
|
||||
printf("-p \"[CLIENT]:[PORT]\" : The ALSA MIDI client and port address to output to (*MANDATORY*).\n");
|
||||
}
|
||||
|
||||
void mididev_add_optstr(char *optstr) {}
|
||||
void mididev_add_optstr(char *optstr) {
|
||||
int main_len = strlen(optstr);
|
||||
strcpy(optstr+main_len, dev_optstr);
|
||||
}
|
||||
|
||||
int mididev_parse_arg(int c, const char *optarg) {
|
||||
size_t len = strlen(optarg);
|
||||
char *temparg = (char*) malloc(len+1);
|
||||
if(temparg == NULL) {
|
||||
fprintf(stderr, "Error allocating memory.\n");
|
||||
return -1;
|
||||
}
|
||||
memcpy(temparg, optarg, len+1);
|
||||
|
||||
char *firstarg = strtok(temparg, ":");
|
||||
if(firstarg == NULL) {
|
||||
fprintf(stderr, "firstarg\n");
|
||||
return -1;
|
||||
}
|
||||
char *secondarg = firstarg + strlen(firstarg) + 1;
|
||||
if(secondarg - temparg >= len) {
|
||||
fprintf(stderr, "%ld %lu\n", secondarg-temparg, len);
|
||||
return -1;
|
||||
}
|
||||
dst_client = (int) strtol(firstarg, NULL, 10);
|
||||
dst_port = (int) strtol(secondarg, NULL, 10);
|
||||
free(temparg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user