diff --git a/linux/alsa/alsa_rawmidi.c b/linux/alsa/alsa_rawmidi.c index d52083740..31658116d 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,9 +440,43 @@ 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 *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"; + 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), + "%s%s (%s)", + prefix, + port_name, + type_name); + } else { + snprintf (name, + sizeof(name), + "%s%s %s (%s)", + prefix, + 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); - jack_port_set_default_metadata(port->jack, port->device_name); + // we just ignore the given alias argument, and use the Jack1 + // port name from above instead -ag + jack_port_set_alias(port->jack, 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 3a5fff014..c890c1bb6 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,21 +511,61 @@ port_t* port_create(alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, const s if (!port->jack_port) goto failed; - jack_port_set_alias (port->jack_port, port->name); - jack_port_set_default_metadata (port->jack_port, device_name); + // 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"; + // 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), + "%s%s (%s)", + prefix, + port_name, + type_name); + } else { + snprintf (port->name, + sizeof(port->name), + "%s%s %s (%s)", + prefix, + device_name, + port_name, + type_name); + } - /* generate an alias */ + // replace all offending characters with ' ' + for (c = port->name; *c; ++c) { + if (!isalnum(*c) && *c != ' ' && *c != '/' && *c != '_' && *c != ':' && *c != '(' && *c != ')') { + *c = ' '; + } + } - 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); + jack_port_set_alias (port->jack_port, port->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 + // 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); if (type == PORT_INPUT) err = alsa_connect_from(self, port->remote.client, port->remote.port);