From 6bc1efeb4a82e7bcf7487f0bcfcc25d3d12469b3 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Mon, 11 Jul 2022 22:46:20 +0100 Subject: [PATCH] ttymidi-sysex: support more System messages add support System Realtime and System Common This patch has also been submitted upstream: https://github.com/cchaussat/ttymidi-sysex/pull/2 Signed-off-by: Daniel Golle --- ...or-System-Realtime-and-System-Common.patch | 240 ++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 multimedia/ttymidi-sysex/patches/100-add-support-for-System-Realtime-and-System-Common.patch diff --git a/multimedia/ttymidi-sysex/patches/100-add-support-for-System-Realtime-and-System-Common.patch b/multimedia/ttymidi-sysex/patches/100-add-support-for-System-Realtime-and-System-Common.patch new file mode 100644 index 0000000000..e8886f47be --- /dev/null +++ b/multimedia/ttymidi-sysex/patches/100-add-support-for-System-Realtime-and-System-Common.patch @@ -0,0 +1,240 @@ +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 {