From 4589f663862d8e7a062b356db3034992a56ed1c9 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Fri, 17 Jun 2022 17:36:31 +0100 Subject: [PATCH] add support System Realtime and System Common https://github.com/cchaussat/ttymidi-sysex/pull/2 Add input and output support for MIDI System Common and System Realtime operations. --- ttymidi-sysex.c | 194 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 181 insertions(+), 13 deletions(-) diff --git a/ttymidi-sysex.c b/ttymidi-sysex.c index ceaeaa9..fc39f49 100644 --- a/ttymidi-sysex.c +++ b/ttymidi-sysex.c @@ -338,18 +338,103 @@ void parse_midi_command(snd_seq_t* seq, int port_out_id, unsigned char *buf, int break; case 0xF0: // *new* - if (buf[0] == 0xF0) { - if (!arguments.silent && arguments.verbose) { - printf("Serial %02X Sysex len = %04X ", operation, buflen); // *new* - int i; - for (i=0; i < buflen; i++) { - printf("%02X ", buf[i]); + switch (channel) { + case 0x0: + if (!arguments.silent && arguments.verbose) { + printf("Serial %02X Sysex len = %04X ", operation, buflen); // *new* + int i; + for (i=0; i < buflen; i++) { + printf("%02X ", buf[i]); + } + printf("\n"); + fflush(stdout); // *new* } - printf("\n"); - fflush(stdout); // *new* - } - // Send sysex message - snd_seq_ev_set_sysex(&ev, buflen, buf); + // Send sysex message + snd_seq_ev_set_sysex(&ev, buflen, buf); + break; + case 0x1: // MTC Quarter Frame package + if (!arguments.silent && arguments.verbose) { + printf("Serial MTC Quarter Frame %02x\n", param1); + fflush(stdout); // *new* + } + snd_seq_ev_set_fixed(&ev); + ev.data.control.value = param1; + ev.type = SND_SEQ_EVENT_QFRAME; + break; + case 0x2: // Song Position + int_param1 = (int) (param1 & 0x7F) + ((param2 & 0x7F) << 7); // *new* + if (!arguments.silent && arguments.verbose) { + printf("Serial Song Position %04x\n", int_param1); + fflush(stdout); // *new* + } + snd_seq_ev_set_fixed(&ev); + ev.data.control.value = int_param1; + ev.type = SND_SEQ_EVENT_SONGPOS; + break; + case 0x3: // Song Select + if (!arguments.silent && arguments.verbose) { + printf("Serial Song Select %02x\n", param1); + fflush(stdout); // *new* + } + snd_seq_ev_set_fixed(&ev); + ev.data.control.value = param1; + ev.type = SND_SEQ_EVENT_SONGSEL; + break; + case 0x6: // Tune Request + if (!arguments.silent && arguments.verbose) { + printf("Serial Tune Request\n"); + fflush(stdout); // *new* + } + snd_seq_ev_set_fixed(&ev); + ev.type = SND_SEQ_EVENT_TUNE_REQUEST; + break; + case 0x8: // Clock + if (!arguments.silent && arguments.verbose) { + printf("Serial Clock\n"); + fflush(stdout); // *new* + } + snd_seq_ev_set_fixed(&ev); + ev.type = SND_SEQ_EVENT_CLOCK; + break; + case 0xA: // Start + if (!arguments.silent && arguments.verbose) { + printf("Serial Start\n"); + fflush(stdout); // *new* + } + snd_seq_ev_set_fixed(&ev); + ev.type = SND_SEQ_EVENT_START; + break; + case 0xB: // Continue + if (!arguments.silent && arguments.verbose) { + printf("Serial Continue\n"); + fflush(stdout); // *new* + } + snd_seq_ev_set_fixed(&ev); + ev.type = SND_SEQ_EVENT_CONTINUE; + break; + case 0xC: // Stop + if (!arguments.silent && arguments.verbose) { + printf("Serial Stop\n"); + fflush(stdout); // *new* + } + snd_seq_ev_set_fixed(&ev); + ev.type = SND_SEQ_EVENT_STOP; + break; + case 0xE: // Active sense + if (!arguments.silent && arguments.verbose) { + printf("Serial Active sense\n"); + fflush(stdout); // *new* + } + snd_seq_ev_set_fixed(&ev); + ev.type = SND_SEQ_EVENT_SENSING; + break; + + default: + if (!arguments.silent) { // *new* + printf("Serial %02X Unknown MIDI System cmd\n", buf[0] & 0xFF); // *new* + fflush(stdout); // *new* + } + break; } break; @@ -464,6 +549,83 @@ void write_midi_action_to_serial_port(snd_seq_t* seq_handle) } break; + case SND_SEQ_EVENT_QFRAME: + bytes[0] = 0xF1; + bytes[1] = ev->data.control.value; + if (!arguments.silent && arguments.verbose) { + printf("Alsa %02X MTC Quarter Frame %02X\n", bytes[0], bytes[1]); + fflush(stdout); // *new* + } + break; + + case SND_SEQ_EVENT_SONGPOS: + bytes[0] = 0xF2; + ev->data.control.value += 8192; + bytes[1] = (unsigned char)(ev->data.control.value & 0x7F); + bytes[2] = (unsigned char)(ev->data.control.value >> 7); + if (!arguments.silent && arguments.verbose) { + printf("Alsa %02X Song Position %04X\n", bytes[0], ev->data.control.value); + fflush(stdout); // *new* + } + break; + + case SND_SEQ_EVENT_SONGSEL: + bytes[0] = 0xF3; + bytes[1] = ev->data.control.value; + if (!arguments.silent && arguments.verbose) { + printf("Alsa %02X Song Select %02X\n", bytes[0], bytes[1]); + fflush(stdout); // *new* + } + break; + + case SND_SEQ_EVENT_TUNE_REQUEST: + bytes[0] = 0xF6; + if (!arguments.silent && arguments.verbose) { + printf("Alsa %02X Tune Request\n", bytes[0]); + fflush(stdout); // *new* + } + break; + + case SND_SEQ_EVENT_CLOCK: + bytes[0] = 0xF8; + if (!arguments.silent && arguments.verbose) { + printf("Alsa %02X Clock\n", bytes[0]); + fflush(stdout); // *new* + } + break; + + case SND_SEQ_EVENT_START: + bytes[0] = 0xFA; + if (!arguments.silent && arguments.verbose) { + printf("Alsa %02X Start\n", bytes[0]); + fflush(stdout); // *new* + } + break; + + case SND_SEQ_EVENT_CONTINUE: + bytes[0] = 0xFB; + if (!arguments.silent && arguments.verbose) { + printf("Alsa %02X Continue\n", bytes[0]); + fflush(stdout); // *new* + } + break; + + case SND_SEQ_EVENT_STOP: + bytes[0] = 0xFC; + if (!arguments.silent && arguments.verbose) { + printf("Alsa %02X Stop\n", bytes[0]); + fflush(stdout); // *new* + } + break; + + case SND_SEQ_EVENT_SENSING: + bytes[0] = 0xFE; + if (!arguments.silent && arguments.verbose) { + printf("Alsa %02X Active Sense\n", bytes[0]); + fflush(stdout); // *new* + } + break; + default: if (!arguments.silent) { // *new* printf("Alsa %02X Unknown MIDI cmd %02X %02X %02X\n", bytes[0]&0xF0, bytes[0]&0x0F, bytes[1], bytes[2]); // *new* @@ -484,8 +646,10 @@ void write_midi_action_to_serial_port(snd_seq_t* seq_handle) if (bytes[0]!=0x00) { bytes[1] = (bytes[1] & 0x7F); // just to be sure that one bit is really zero - if (bytes[2]==0xFF) { + if (bytes[2]==0xFF || bytes[0]==0xF1 || bytes[0]==0xF3 || bytes[0]==0xF5) write(serial, bytes, 2); + else if (bytes[0]==0xF4 || bytes[0]==0xF6 || bytes[0]>=0xF8) { + write(serial, bytes, 1); } else { bytes[2] = (bytes[2] & 0x7F); write(serial, bytes, 3); @@ -570,7 +734,11 @@ void* read_midi_from_serial_port(void* seq) break; } buf[0] = buf[i]; - if(buf[0] != 0xF0) //if not SysEx *new* + if (buf[0] == 0xF1 || buf[0] == 0xF3 || buf[0] == 0xF5) + bytesleft = 1; + else if (buf[0] >= 0xF4 || buf[0] >= 0xF6 || (buf[0] >= 0xF8 && buf[0] <= 0xFE)) + bytesleft = 0; + else if (buf[0] != 0xF0) //if not SysEx *new* bytesleft = 3; i = 1; } else {