From c3ff1936b56ef592e171a78f4a847046c38def45 Mon Sep 17 00:00:00 2001 From: Albert Graef Date: Tue, 25 Jul 2023 19:46:25 +0200 Subject: [PATCH 1/3] Rework the seqmidi aliases. - The 1st alias is now the Jack1 MIDI port name with alsa_midi prefix. - This 2nd alias is basically the same as the 1st alias with the alsa_midi prefix stripped, so that devices are listed under the ALSA names. Also fixed the "capture" and "playback" port type names which were the wrong way round. --- linux/alsa/alsa_seqmidi.c | 66 ++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/linux/alsa/alsa_seqmidi.c b/linux/alsa/alsa_seqmidi.c index 3a5fff014..8a6b77d89 100644 --- a/linux/alsa/alsa_seqmidi.c +++ b/linux/alsa/alsa_seqmidi.c @@ -147,13 +147,13 @@ static port_type_t port_type[2] = { { SND_SEQ_PORT_CAP_SUBS_READ, JackPortIsOutput, - "playback", + "capture", do_jack_input }, { SND_SEQ_PORT_CAP_SUBS_WRITE, JackPortIsInput, - "capture", + "playback", do_jack_output } }; @@ -493,15 +493,6 @@ port_t* port_create(alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, const s snd_seq_client_info_alloca (&client_info); snd_seq_get_any_client_info (self->seq, addr.client, client_info); - const char *device_name = snd_seq_client_info_get_name(client_info); - snprintf(port->name, sizeof(port->name), "alsa_pcm:%s/midi_%s_%d", - device_name, port_type[type].name, addr.port+1); - - // replace all offending characters by - - for (c = port->name; *c; ++c) - if (!isalnum(*c) && *c != '/' && *c != '_' && *c != ':' && *c != '(' && *c != ')') - *c = '-'; - jack_caps = port_type[type].jack_caps; /* mark anything that looks like a hardware port as physical&terminal */ @@ -520,18 +511,55 @@ port_t* port_create(alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, const s if (!port->jack_port) goto failed; + // First alias: Jack1-compatible port name. -ag + const char *device_name = snd_seq_client_info_get_name(client_info); + const char* port_name = snd_seq_port_info_get_name (info); + const char* type_name = jack_caps & JackPortIsOutput ? "out" : "in"; + // This code is pilfered from Jack1. -ag + if (strstr (port_name, device_name) == port_name) { + /* entire client name is part of the port name so don't replicate it */ + snprintf (port->name, + sizeof(port->name), + "alsa_midi:%s (%s)", + port_name, + type_name); + } else { + snprintf (port->name, + sizeof(port->name), + "alsa_midi:%s %s (%s)", + device_name, + port_name, + type_name); + } + + // replace all offending characters with ' ' + for (c = port->name; *c; ++c) { + if (!isalnum(*c) && *c != ' ' && *c != '/' && *c != '_' && *c != ':' && *c != '(' && *c != ')') { + *c = ' '; + } + } + jack_port_set_alias (port->jack_port, port->name); jack_port_set_default_metadata (port->jack_port, device_name); - /* generate an alias */ - - snprintf(port->name, sizeof(port->name), "%s:midi/%s_%d", - snd_seq_client_info_get_name (client_info), port_type[type].name, addr.port+1); + // Second alias: Strip the alsa_midi prefix, so that devices appear + // under their ALSA names. Use the ALSA port names (without device + // prefix) for the individual ports. -ag + if (strstr (port_name, device_name) == port_name) { + // remove the device name prefix from the port name if present + port_name += strlen(device_name); + while (*port_name == ' ' || *port_name == '\t') + port_name++; + } + snprintf(port->name, sizeof(port->name), "%s:%s (%s)", + device_name, port_name, port_type[type].name); - // replace all offending characters by - - for (c = port->name; *c; ++c) - if (!isalnum(*c) && *c != '/' && *c != '_' && *c != ':' && *c != '(' && *c != ')') - *c = '-'; + // replace all offending characters with ' ' + for (c = port->name; *c; ++c) { + if (!isalnum(*c) && *c != ' ' && *c != '/' && *c != '_' && *c != ':' && *c != '(' && *c != ')') { + *c = ' '; + } + } jack_port_set_alias (port->jack_port, port->name); jack_port_set_default_metadata (port->jack_port, device_name); From fd4ab30737735a878d7fefeb350b55ca4dc4d69c Mon Sep 17 00:00:00 2001 From: Albert Graef Date: Tue, 25 Jul 2023 20:13:57 +0200 Subject: [PATCH 2/3] Rework the rawmidi alias. Like in alsa_seqmidi.c, the 1st alias is now the Jack1 MIDI port name with alsa_midi prefix. --- linux/alsa/alsa_rawmidi.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/linux/alsa/alsa_rawmidi.c b/linux/alsa/alsa_rawmidi.c index d52083740..0f6b137cc 100644 --- a/linux/alsa/alsa_rawmidi.c +++ b/linux/alsa/alsa_rawmidi.c @@ -91,6 +91,7 @@ struct midi_port_t { char dev[16]; char name[64]; char device_name[64]; + char subdev_name[64]; jack_port_t *jack; snd_rawmidi_t *rawmidi; @@ -415,6 +416,7 @@ void midi_port_init(const alsa_rawmidi_t *midi, midi_port_t *port, snd_rawmidi_i name = snd_rawmidi_info_get_subdevice_name(info); if (!strlen(name)) name = port->device_name; + strncpy(port->subdev_name, name, sizeof(port->subdev_name)); snprintf(port->name, sizeof(port->name), "%s %s %s", port->id.id[2] ? "out":"in", port->dev, name); // replace all offending characters with '-' @@ -438,8 +440,38 @@ inline int midi_port_open_jack(alsa_rawmidi_t *midi, midi_port_t *port, int type port->jack = jack_port_register(midi->client, name, JACK_DEFAULT_MIDI_TYPE, type | JackPortIsPhysical | JackPortIsTerminal, 0); + // Like in alsa_seqmidi.c, use the Jack1 port name as alias. -ag + const char* device_name = port->device_name; + const char* port_name = port->subdev_name; + const char *type_name = (type & JackPortIsOutput) ? "out" : "in"; + if (strstr (port_name, device_name) == port_name) { + /* entire client name is part of the port name so don't replicate it */ + snprintf (name, + sizeof(name), + "alsa_midi:%s (%s)", + port_name, + type_name); + } else { + snprintf (name, + sizeof(name), + "alsa_midi:%s %s (%s)", + device_name, + port_name, + type_name); + } + + // replace all offending characters with ' ' + char *c; + for (c = name; *c; ++c) { + if (!isalnum(*c) && *c != ' ' && *c != '/' && *c != '_' && *c != ':' && *c != ',' && *c != '(' && *c != ')') { + *c = ' '; + } + } + if (port->jack) { - jack_port_set_alias(port->jack, alias); + // we just ignore the given alias argument, and use the Jack1 + // port name from above instead -ag + jack_port_set_alias(port->jack, name); jack_port_set_default_metadata(port->jack, port->device_name); } From c3b6d566af76e93a8879ea644ed259b7464e9976 Mon Sep 17 00:00:00 2001 From: Albert Graef Date: Thu, 27 Jul 2023 08:44:27 +0200 Subject: [PATCH 3/3] Rework pretty-name metadata. The rawmidi and seqmidi pretty-name metadata now uses the same Jack1 port name as the 1st alias, without the alsa_midi: prefix. --- linux/alsa/alsa_rawmidi.c | 10 +++++++--- linux/alsa/alsa_seqmidi.c | 11 +++++++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/linux/alsa/alsa_rawmidi.c b/linux/alsa/alsa_rawmidi.c index 0f6b137cc..31658116d 100644 --- a/linux/alsa/alsa_rawmidi.c +++ b/linux/alsa/alsa_rawmidi.c @@ -441,6 +441,7 @@ inline int midi_port_open_jack(alsa_rawmidi_t *midi, midi_port_t *port, int type type | JackPortIsPhysical | JackPortIsTerminal, 0); // Like in alsa_seqmidi.c, use the Jack1 port name as alias. -ag + const char *prefix = "alsa_midi:"; const char* device_name = port->device_name; const char* port_name = port->subdev_name; const char *type_name = (type & JackPortIsOutput) ? "out" : "in"; @@ -448,13 +449,15 @@ inline int midi_port_open_jack(alsa_rawmidi_t *midi, midi_port_t *port, int type /* entire client name is part of the port name so don't replicate it */ snprintf (name, sizeof(name), - "alsa_midi:%s (%s)", + "%s%s (%s)", + prefix, port_name, type_name); } else { snprintf (name, sizeof(name), - "alsa_midi:%s %s (%s)", + "%s%s %s (%s)", + prefix, device_name, port_name, type_name); @@ -472,7 +475,8 @@ inline int midi_port_open_jack(alsa_rawmidi_t *midi, midi_port_t *port, int type // we just ignore the given alias argument, and use the Jack1 // port name from above instead -ag jack_port_set_alias(port->jack, name); - jack_port_set_default_metadata(port->jack, port->device_name); + // Pretty-name metadata is the same as alias without the prefix. + jack_port_set_default_metadata (port->jack, name+strlen(prefix)); } return port->jack == NULL; diff --git a/linux/alsa/alsa_seqmidi.c b/linux/alsa/alsa_seqmidi.c index 8a6b77d89..c890c1bb6 100644 --- a/linux/alsa/alsa_seqmidi.c +++ b/linux/alsa/alsa_seqmidi.c @@ -512,6 +512,7 @@ port_t* port_create(alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, const s goto failed; // First alias: Jack1-compatible port name. -ag + const char *prefix = "alsa_midi:"; const char *device_name = snd_seq_client_info_get_name(client_info); const char* port_name = snd_seq_port_info_get_name (info); const char* type_name = jack_caps & JackPortIsOutput ? "out" : "in"; @@ -520,13 +521,15 @@ port_t* port_create(alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, const s /* entire client name is part of the port name so don't replicate it */ snprintf (port->name, sizeof(port->name), - "alsa_midi:%s (%s)", + "%s%s (%s)", + prefix, port_name, type_name); } else { snprintf (port->name, sizeof(port->name), - "alsa_midi:%s %s (%s)", + "%s%s %s (%s)", + prefix, device_name, port_name, type_name); @@ -540,7 +543,8 @@ port_t* port_create(alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, const s } jack_port_set_alias (port->jack_port, port->name); - jack_port_set_default_metadata (port->jack_port, device_name); + // Pretty-name metadata is the same as first alias without the prefix. + jack_port_set_default_metadata (port->jack_port, port->name+strlen(prefix)); // Second alias: Strip the alsa_midi prefix, so that devices appear // under their ALSA names. Use the ALSA port names (without device @@ -562,7 +566,6 @@ port_t* port_create(alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, const s } jack_port_set_alias (port->jack_port, port->name); - jack_port_set_default_metadata (port->jack_port, device_name); if (type == PORT_INPUT) err = alsa_connect_from(self, port->remote.client, port->remote.port);