From 1a737a9fed8eb7f59fa47a31f5655be5439ce3be Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 27 Jan 2025 13:05:21 +0100 Subject: [PATCH] jack: use a new JackPortIsMIDI2 flag The JACK2 maintainer would prefer to use a new port flag to mark the MIDI2 capability of the port and keep the port type as MIDI. Add the proposed flags to the API. If we register a MIDI port with the MIDI2 flag, promote it to UMP. Expose v1 MIDI ports with the MIDI DSP property again. If we see an UMP port, set the MIDI2 flag on the port. This is functionaly equivalent to what we have. Old jack midi ports will now however not have the UMP DSP format but the old MIDI format so that we can, in the JACK API, make a distinction between MIDI1 and MIDI2 ports. --- pipewire-jack/examples/ump-source.c | 4 ++-- pipewire-jack/jack/types.h | 23 +++++++++++++++++++++++ pipewire-jack/src/pipewire-jack.c | 8 +++++++- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/pipewire-jack/examples/ump-source.c b/pipewire-jack/examples/ump-source.c index e3cbb8042..274d72487 100644 --- a/pipewire-jack/examples/ump-source.c +++ b/pipewire-jack/examples/ump-source.c @@ -91,8 +91,8 @@ int main(int argc, char *argv[]) /* the UMP port type allows both sending and receiving of UMP * messages, which can contain MIDI 1.0 and MIDI 2.0 messages. */ data.out_port = jack_port_register (data.client, "output", - JACK_DEFAULT_UMP_TYPE, - JackPortIsOutput, 0); + JACK_DEFAULT_MIDI_TYPE, + JackPortIsOutput | JackPortIsMIDI2, 0); if (data.out_port == NULL) { fprintf(stderr, "no more JACK ports available\n"); diff --git a/pipewire-jack/jack/types.h b/pipewire-jack/jack/types.h index 006064382..206d72702 100644 --- a/pipewire-jack/jack/types.h +++ b/pipewire-jack/jack/types.h @@ -515,6 +515,29 @@ enum JackPortFlags { */ JackPortIsTerminal = 0x10, + /** + * if JackPortIsCV is set, then the port buffer represents audio-rate + * control data rather than audio. + * + * Clients SHOULD prevent connections between Audio and CV ports. + * + * To make the ports more meaningful, clients can add meta-data to them. + * It is recommended to set these 2 in particular: + * - http://lv2plug.in/ns/lv2core#minimum + * - http://lv2plug.in/ns/lv2core#maximum + */ + JackPortIsCV = 0x20, + + /** + * if JackPortIsMIDI2 is set, then the port expects to receive MIDI2 data. + * + * JACK will automatically convert MIDI1 data into MIDI2 for this port. + * + * for ports without this flag JACK will convert MIDI2 into MIDI1 + * as much possible, some events might be skipped. + */ + JackPortIsMIDI2 = 0x20, + }; /** diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c index 0a77e8c60..beda21293 100644 --- a/pipewire-jack/src/pipewire-jack.c +++ b/pipewire-jack/src/pipewire-jack.c @@ -3438,8 +3438,8 @@ static const char* type_to_format_dsp(jack_port_type_id_t type_id) case TYPE_ID_OSC: return JACK_DEFAULT_OSC_TYPE; case TYPE_ID_MIDI: + return JACK_DEFAULT_MIDI_TYPE; case TYPE_ID_UMP: - /* all exposed to PipeWire as UMP */ return JACK_DEFAULT_UMP_TYPE; default: return NULL; @@ -3818,6 +3818,9 @@ static void registry_event_global(void *data, uint32_t id, if ((str = spa_dict_lookup(props, PW_KEY_PORT_NAME)) == NULL) goto exit; + if (type_id == TYPE_ID_UMP) + flags |= JackPortIsMIDI2; + spa_dict_for_each(item, props) { if (spa_streq(item->key, PW_KEY_PORT_DIRECTION)) { if (spa_streq(item->value, "in")) @@ -5437,6 +5440,9 @@ jack_port_t * jack_port_register (jack_client_t *client, pw_log_warn("unknown port type %s", port_type); return NULL; } + if (type_id == TYPE_ID_MIDI && (flags & JackPortIsMIDI2)) + type_id = TYPE_ID_UMP; + len = snprintf(name, sizeof(name), "%s:%s", c->name, port_name); if (len < 0 || (size_t)len >= sizeof(name)) { pw_log_warn("%p: name \"%s:%s\" too long", c,