Skip to content

Commit b83d234

Browse files
authored
Jack MIDI portnames (fixes #944) (#945)
* 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. * Rework the rawmidi alias. Like in alsa_seqmidi.c, the 1st alias is now the Jack1 MIDI port name with alsa_midi prefix. * 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.
1 parent f4da9d2 commit b83d234

File tree

2 files changed

+90
-23
lines changed

2 files changed

+90
-23
lines changed

linux/alsa/alsa_rawmidi.c

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ struct midi_port_t {
9191
char dev[16];
9292
char name[64];
9393
char device_name[64];
94+
char subdev_name[64];
9495

9596
jack_port_t *jack;
9697
snd_rawmidi_t *rawmidi;
@@ -415,6 +416,7 @@ void midi_port_init(const alsa_rawmidi_t *midi, midi_port_t *port, snd_rawmidi_i
415416
name = snd_rawmidi_info_get_subdevice_name(info);
416417
if (!strlen(name))
417418
name = port->device_name;
419+
strncpy(port->subdev_name, name, sizeof(port->subdev_name));
418420
snprintf(port->name, sizeof(port->name), "%s %s %s", port->id.id[2] ? "out":"in", port->dev, name);
419421

420422
// 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
438440
port->jack = jack_port_register(midi->client, name, JACK_DEFAULT_MIDI_TYPE,
439441
type | JackPortIsPhysical | JackPortIsTerminal, 0);
440442

443+
// Like in alsa_seqmidi.c, use the Jack1 port name as alias. -ag
444+
const char *prefix = "alsa_midi:";
445+
const char* device_name = port->device_name;
446+
const char* port_name = port->subdev_name;
447+
const char *type_name = (type & JackPortIsOutput) ? "out" : "in";
448+
if (strstr (port_name, device_name) == port_name) {
449+
/* entire client name is part of the port name so don't replicate it */
450+
snprintf (name,
451+
sizeof(name),
452+
"%s%s (%s)",
453+
prefix,
454+
port_name,
455+
type_name);
456+
} else {
457+
snprintf (name,
458+
sizeof(name),
459+
"%s%s %s (%s)",
460+
prefix,
461+
device_name,
462+
port_name,
463+
type_name);
464+
}
465+
466+
// replace all offending characters with ' '
467+
char *c;
468+
for (c = name; *c; ++c) {
469+
if (!isalnum(*c) && *c != ' ' && *c != '/' && *c != '_' && *c != ':' && *c != ',' && *c != '(' && *c != ')') {
470+
*c = ' ';
471+
}
472+
}
473+
441474
if (port->jack) {
442-
jack_port_set_alias(port->jack, alias);
443-
jack_port_set_default_metadata(port->jack, port->device_name);
475+
// we just ignore the given alias argument, and use the Jack1
476+
// port name from above instead -ag
477+
jack_port_set_alias(port->jack, name);
478+
// Pretty-name metadata is the same as alias without the prefix.
479+
jack_port_set_default_metadata (port->jack, name+strlen(prefix));
444480
}
445481

446482
return port->jack == NULL;

linux/alsa/alsa_seqmidi.c

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,13 @@ static port_type_t port_type[2] = {
147147
{
148148
SND_SEQ_PORT_CAP_SUBS_READ,
149149
JackPortIsOutput,
150-
"playback",
150+
"capture",
151151
do_jack_input
152152
},
153153
{
154154
SND_SEQ_PORT_CAP_SUBS_WRITE,
155155
JackPortIsInput,
156-
"capture",
156+
"playback",
157157
do_jack_output
158158
}
159159
};
@@ -493,15 +493,6 @@ port_t* port_create(alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, const s
493493
snd_seq_client_info_alloca (&client_info);
494494
snd_seq_get_any_client_info (self->seq, addr.client, client_info);
495495

496-
const char *device_name = snd_seq_client_info_get_name(client_info);
497-
snprintf(port->name, sizeof(port->name), "alsa_pcm:%s/midi_%s_%d",
498-
device_name, port_type[type].name, addr.port+1);
499-
500-
// replace all offending characters by -
501-
for (c = port->name; *c; ++c)
502-
if (!isalnum(*c) && *c != '/' && *c != '_' && *c != ':' && *c != '(' && *c != ')')
503-
*c = '-';
504-
505496
jack_caps = port_type[type].jack_caps;
506497

507498
/* 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
520511
if (!port->jack_port)
521512
goto failed;
522513

523-
jack_port_set_alias (port->jack_port, port->name);
524-
jack_port_set_default_metadata (port->jack_port, device_name);
514+
// First alias: Jack1-compatible port name. -ag
515+
const char *prefix = "alsa_midi:";
516+
const char *device_name = snd_seq_client_info_get_name(client_info);
517+
const char* port_name = snd_seq_port_info_get_name (info);
518+
const char* type_name = jack_caps & JackPortIsOutput ? "out" : "in";
519+
// This code is pilfered from Jack1. -ag
520+
if (strstr (port_name, device_name) == port_name) {
521+
/* entire client name is part of the port name so don't replicate it */
522+
snprintf (port->name,
523+
sizeof(port->name),
524+
"%s%s (%s)",
525+
prefix,
526+
port_name,
527+
type_name);
528+
} else {
529+
snprintf (port->name,
530+
sizeof(port->name),
531+
"%s%s %s (%s)",
532+
prefix,
533+
device_name,
534+
port_name,
535+
type_name);
536+
}
525537

526-
/* generate an alias */
538+
// replace all offending characters with ' '
539+
for (c = port->name; *c; ++c) {
540+
if (!isalnum(*c) && *c != ' ' && *c != '/' && *c != '_' && *c != ':' && *c != '(' && *c != ')') {
541+
*c = ' ';
542+
}
543+
}
527544

528-
snprintf(port->name, sizeof(port->name), "%s:midi/%s_%d",
529-
snd_seq_client_info_get_name (client_info), port_type[type].name, addr.port+1);
545+
jack_port_set_alias (port->jack_port, port->name);
546+
// Pretty-name metadata is the same as first alias without the prefix.
547+
jack_port_set_default_metadata (port->jack_port, port->name+strlen(prefix));
548+
549+
// Second alias: Strip the alsa_midi prefix, so that devices appear
550+
// under their ALSA names. Use the ALSA port names (without device
551+
// prefix) for the individual ports. -ag
552+
if (strstr (port_name, device_name) == port_name) {
553+
// remove the device name prefix from the port name if present
554+
port_name += strlen(device_name);
555+
while (*port_name == ' ' || *port_name == '\t')
556+
port_name++;
557+
}
558+
snprintf(port->name, sizeof(port->name), "%s:%s (%s)",
559+
device_name, port_name, port_type[type].name);
530560

531-
// replace all offending characters by -
532-
for (c = port->name; *c; ++c)
533-
if (!isalnum(*c) && *c != '/' && *c != '_' && *c != ':' && *c != '(' && *c != ')')
534-
*c = '-';
561+
// replace all offending characters with ' '
562+
for (c = port->name; *c; ++c) {
563+
if (!isalnum(*c) && *c != ' ' && *c != '/' && *c != '_' && *c != ':' && *c != '(' && *c != ')') {
564+
*c = ' ';
565+
}
566+
}
535567

536568
jack_port_set_alias (port->jack_port, port->name);
537-
jack_port_set_default_metadata (port->jack_port, device_name);
538569

539570
if (type == PORT_INPUT)
540571
err = alsa_connect_from(self, port->remote.client, port->remote.port);

0 commit comments

Comments
 (0)