You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
448 lines
14 KiB
448 lines
14 KiB
1.) Human-readable portnames on larger cards where "playback_56" is
|
|
simply to cumbersome to figure out what's actually connected
|
|
2.) People who travel with ADAT-ADCs/DACs, but connect them via
|
|
different interfaces in different locations, e.g. a Multiface
|
|
when on the road and a RayDat when in the studio. Despite the
|
|
different cards, the port names and hence any ardour session
|
|
would remain intact.
|
|
http://adi.loris.tv/jackd2-portnames.png
|
|
alsa_pcm:hw:1,0:out1
|
|
system:capture_1
|
|
alsa_pcm:hw:1,0:out2
|
|
system:capture_2
|
|
--- /dev/null
|
|
+++ b/linux/alsa/port_names.c
|
|
@@ -0,0 +1,179 @@
|
|
+/* -*- mode: c; c-file-style: "linux"; -*- */
|
|
+/*
|
|
+ Copyright (C) 2010 Florian Faber, faber@faberman.de
|
|
+
|
|
+ This program is free software; you can redistribute it and/or modify
|
|
+ it under the terms of the GNU General Public License as published by
|
|
+ the Free Software Foundation; either version 2 of the License, or
|
|
+ (at your option) any later version.
|
|
+
|
|
+ This program is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ GNU General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU General Public License
|
|
+ along with this program; if not, write to the Free Software
|
|
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
+
|
|
+*/
|
|
+
|
|
+
|
|
+#include <math.h>
|
|
+#include <stdio.h>
|
|
+#include <memory.h>
|
|
+#include <unistd.h>
|
|
+#include <stdlib.h>
|
|
+#include <errno.h>
|
|
+#include <stdarg.h>
|
|
+#include <signal.h>
|
|
+#include <sys/types.h>
|
|
+#include <regex.h>
|
|
+#include <string.h>
|
|
+
|
|
+#include "alsa_driver.h"
|
|
+
|
|
+
|
|
+static int port_names_load_portfile(alsa_driver_t *driver, const char *filename, char **buf, const unsigned int offset, const unsigned int num) {
|
|
+ int fh, i, ret, lineno, id, res=0;
|
|
+ char line[256];
|
|
+
|
|
+ printf("Trying to load portnames from %s\n", filename);
|
|
+ fh = open(filename, O_RDONLY);
|
|
+ if (-1!=fh) {
|
|
+ res = 1;
|
|
+ i = 0;
|
|
+ lineno = 1;
|
|
+ for (;;) {
|
|
+ ret = read(fh, &line[i], 1);
|
|
+ if (0==ret) {
|
|
+ break;
|
|
+ } else if (-1==ret) {
|
|
+ sprintf(stderr, "Error while reading \"%s\": %s", filename, strerror(errno));
|
|
+ break;
|
|
+ }
|
|
+ if (0x0A==line[i]) {
|
|
+ /* new line, parse input */
|
|
+ line[i] = 0;
|
|
+
|
|
+ if ('#' != line[0]) {
|
|
+ i=0;
|
|
+ while ((i<255) && (line[i]!='=')) i++;
|
|
+ if (255==i) {
|
|
+ sprintf(stderr, "Error while reading \"%s\": Line %d has no key=value syntax!", filename, lineno);
|
|
+ } else {
|
|
+ line[i] = 0;
|
|
+ id = atoi(line);
|
|
+ if ((id>=1) && (id<=num)) {
|
|
+ if (NULL==buf[id-1+offset]) {
|
|
+ /* don't overwrite existing names */
|
|
+ buf[id-1+offset] = strdup(&line[i+1]);
|
|
+ }
|
|
+ } else {
|
|
+ sprintf(stderr, "Error while reading \"%s\": Key %d out of range in line %d (1..%d)", filename, id, lineno, num);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ i = 0;
|
|
+ lineno++;
|
|
+ } else {
|
|
+ i++;
|
|
+ if (i==255) {
|
|
+ sprintf(stderr, "Error while reading \"%s\": Line %d is too long", filename, lineno);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ (void) close(fh);
|
|
+ }
|
|
+
|
|
+ return res;
|
|
+}
|
|
+
|
|
+
|
|
+static void port_names_default_portnames(char **buf, const unsigned int offset, const unsigned int num, const char *defaultname) {
|
|
+ unsigned int i;
|
|
+ char line[256];
|
|
+
|
|
+ /* Fill in default names */
|
|
+ for (i=0; i<num; i++) {
|
|
+ if (NULL==buf[i+offset]) {
|
|
+ snprintf(line, 255, defaultname, i+1);
|
|
+ buf[i+offset] = strdup(line);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+char** port_names_get_portnames(alsa_driver_t *driver) {
|
|
+ snd_ctl_card_info_t *card_info;
|
|
+ int err;
|
|
+ const char *card_name = NULL;
|
|
+ char filename[256], *speed;
|
|
+ char **buf;
|
|
+
|
|
+ printf("Using port names patch v0.1 (07.04.2010)\n");
|
|
+
|
|
+ if (driver->frame_rate > 96000) {
|
|
+ speed="qs";
|
|
+ } else if (driver->frame_rate > 48000) {
|
|
+ speed="ds";
|
|
+ } else {
|
|
+ speed="ss";
|
|
+ }
|
|
+
|
|
+ snd_ctl_card_info_alloca(&card_info);
|
|
+ err = snd_ctl_card_info(driver->ctl_handle, card_info);
|
|
+ if (err >= 0) {
|
|
+ card_name = snd_ctl_card_info_get_name(card_info);
|
|
+ } else {
|
|
+ card_name = "noname";
|
|
+ }
|
|
+
|
|
+ buf = malloc(sizeof(char *)*(driver->capture_nchannels + driver->playback_nchannels));
|
|
+ if (NULL==buf) {
|
|
+ sprintf(stderr, "ALSA: Not enough memory for %d port names", driver->capture_nchannels + driver->playback_nchannels);
|
|
+ return NULL;
|
|
+ }
|
|
+ bzero(buf, sizeof(char *)*(driver->capture_nchannels + driver->playback_nchannels));
|
|
+
|
|
+ /* Read port names from special to general:
|
|
+ * Begin with user and speed specific port names */
|
|
+ snprintf(filename, 255, "%s/.config/jack/cards/%s.%s.ports.in", getenv("HOME"), card_name, speed);
|
|
+ (void) port_names_load_portfile(driver, filename, buf, 0, driver->capture_nchannels);
|
|
+
|
|
+ /* Now user general */
|
|
+ snprintf(filename, 255, "%s/.config/jack/cards/%s.ports.in", getenv("HOME"), card_name);
|
|
+ (void) port_names_load_portfile(driver, filename, buf, 0, driver->capture_nchannels);
|
|
+
|
|
+ /* System speed specific */
|
|
+ snprintf(filename, 255, "/etc/jack/cards/%s.%s.ports.in", card_name, speed);
|
|
+ (void) port_names_load_portfile(driver, filename, buf, 0, driver->capture_nchannels);
|
|
+
|
|
+ /* System general */
|
|
+ snprintf(filename, 255, "/etc/jack/cards/%s.ports.in", card_name);
|
|
+ (void) port_names_load_portfile(driver, filename, buf, 0, driver->capture_nchannels);
|
|
+
|
|
+ /* Fill all still unnamed ports with default names */
|
|
+ port_names_default_portnames(buf, 0, driver->capture_nchannels, "capture_%lu");
|
|
+
|
|
+
|
|
+ /* Same procedure for the playback channels */
|
|
+ snprintf(filename, 255, "%s/.config/jack/cards/%s.%s.ports.out", getenv("HOME"), card_name, speed);
|
|
+ (void) port_names_load_portfile(driver, filename, buf, driver->capture_nchannels, driver->playback_nchannels);
|
|
+
|
|
+ snprintf(filename, 255, "%s/.config/jack/cards/%s.ports.out", getenv("HOME"), card_name);
|
|
+ (void) port_names_load_portfile(driver, filename, buf, driver->capture_nchannels, driver->playback_nchannels);
|
|
+
|
|
+ snprintf(filename, 255, "/etc/jack/cards/%s.%s.ports.out", card_name, speed);
|
|
+ (void) port_names_load_portfile(driver, filename, buf, driver->capture_nchannels, driver->playback_nchannels);
|
|
+
|
|
+ snprintf(filename, 255, "/etc/jack/cards/%s.ports.out", card_name);
|
|
+ (void) port_names_load_portfile(driver, filename, buf, driver->capture_nchannels, driver->playback_nchannels);
|
|
+
|
|
+ port_names_default_portnames(buf, driver->capture_nchannels, driver->playback_nchannels, "playback_%lu");
|
|
+
|
|
+ return buf;
|
|
+}
|
|
--- /dev/null
|
|
+++ b/linux/alsa/port_names.h
|
|
@@ -0,0 +1,34 @@
|
|
+/*
|
|
+ Copyright (C) 2010 Florian Faber, faber@faberman.de
|
|
+
|
|
+ This program is free software; you can redistribute it and/or modify
|
|
+ it under the terms of the GNU General Public License as published by
|
|
+ the Free Software Foundation; either version 2 of the License, or
|
|
+ (at your option) any later version.
|
|
+
|
|
+ This program is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ GNU General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU General Public License
|
|
+ along with this program; if not, write to the Free Software
|
|
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
+
|
|
+*/
|
|
+
|
|
+#ifndef __jack_port_names_h__
|
|
+#define __jack_port_names_h__
|
|
+
|
|
+#ifdef __cplusplus
|
|
+extern "C"
|
|
+{
|
|
+#endif
|
|
+
|
|
+char** port_names_get_portnames(alsa_driver_t *driver);
|
|
+
|
|
+#ifdef __cplusplus
|
|
+}
|
|
+#endif
|
|
+
|
|
+#endif /* __jack_port_names_h__ */
|
|
--- a/linux/alsa/JackAlsaDriver.cpp
|
|
+++ b/linux/alsa/JackAlsaDriver.cpp
|
|
@@ -42,6 +42,7 @@
|
|
#include "JackPosixThread.h"
|
|
#include "JackCompilerDeps.h"
|
|
#include "JackServerGlobals.h"
|
|
+#include "port_names.h"
|
|
|
|
namespace Jack
|
|
{
|
|
@@ -97,6 +98,8 @@
|
|
unsigned long port_flags = (unsigned long)CaptureDriverFlags;
|
|
char name[REAL_JACK_PORT_NAME_SIZE];
|
|
char alias[REAL_JACK_PORT_NAME_SIZE];
|
|
+ char old_name[REAL_JACK_PORT_NAME_SIZE];
|
|
+ char **portnames;
|
|
|
|
assert(fCaptureChannels < DRIVER_PORT_NUM);
|
|
assert(fPlaybackChannels < DRIVER_PORT_NUM);
|
|
@@ -112,13 +115,17 @@
|
|
|
|
jack_log("JackAlsaDriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
|
|
|
|
+ portnames = port_names_get_portnames(alsa_driver);
|
|
+
|
|
for (int i = 0; i < fCaptureChannels; i++) {
|
|
snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1);
|
|
- snprintf(name, sizeof(name), "%s:capture_%d", fClientControl.fName, i + 1);
|
|
+ snprintf(old_name, sizeof(old_name), "%s:capture_%d", fClientControl.fName, i + 1);
|
|
+ snprintf(name, sizeof(name), "%s:%s", fClientControl.fName, portnames[i]);
|
|
if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize, &port_index) < 0) {
|
|
jack_error("driver: cannot register port for %s", name);
|
|
return -1;
|
|
}
|
|
+ free(portnames[i]);
|
|
port = fGraphManager->GetPort(port_index);
|
|
port->SetAlias(alias);
|
|
fCapturePortList[i] = port_index;
|
|
@@ -129,11 +136,13 @@
|
|
|
|
for (int i = 0; i < fPlaybackChannels; i++) {
|
|
snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1);
|
|
- snprintf(name, sizeof(name), "%s:playback_%d", fClientControl.fName, i + 1);
|
|
+ snprintf(old_name, sizeof(old_name), "%s:playback_%d", fClientControl.fName, i + 1);
|
|
+ snprintf(name, sizeof(name), "%s:%s", fClientControl.fName, portnames[i+fCaptureChannels]);
|
|
if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize, &port_index) < 0) {
|
|
jack_error("driver: cannot register port for %s", name);
|
|
return -1;
|
|
}
|
|
+ free(portnames[i+fCaptureChannels]);
|
|
port = fGraphManager->GetPort(port_index);
|
|
port->SetAlias(alias);
|
|
fPlaybackPortList[i] = port_index;
|
|
@@ -151,6 +160,8 @@
|
|
}
|
|
}
|
|
|
|
+ free(portnames);
|
|
+
|
|
UpdateLatencies();
|
|
|
|
if (alsa_driver->midi) {
|
|
--- a/linux/wscript
|
|
+++ b/linux/wscript
|
|
@@ -55,6 +55,7 @@
|
|
'alsa/hdsp.c',
|
|
'alsa/alsa_driver.c',
|
|
'alsa/hammerfall.c',
|
|
+ 'alsa/port_names.c',
|
|
'alsa/ice1712.c'
|
|
]
|
|
|
|
alsa_pcm:hw:1,0:out1
|
|
system:capture_1
|
|
alsa_pcm:hw:1,0:out2
|
|
system:capture_2
|
|
alsa_pcm:hw:1,0:out3
|
|
system:capture_3
|
|
alsa_pcm:hw:1,0:out4
|
|
system:capture_4
|
|
alsa_pcm:hw:1,0:out5
|
|
system:capture_5
|
|
alsa_pcm:hw:1,0:out6
|
|
system:capture_6
|
|
alsa_pcm:hw:1,0:out7
|
|
system:capture_7
|
|
alsa_pcm:hw:1,0:out8
|
|
system:capture_8
|
|
alsa_pcm:hw:1,0:out9
|
|
system:capture_9
|
|
alsa_pcm:hw:1,0:out10
|
|
system:capture_10
|
|
alsa_pcm:hw:1,0:out11
|
|
system:capture_11
|
|
alsa_pcm:hw:1,0:out12
|
|
system:capture_12
|
|
alsa_pcm:hw:1,0:out13
|
|
system:capture_13
|
|
alsa_pcm:hw:1,0:out14
|
|
system:capture_14
|
|
alsa_pcm:hw:1,0:out15
|
|
system:capture_15
|
|
alsa_pcm:hw:1,0:out16
|
|
system:capture_16
|
|
alsa_pcm:hw:1,0:out17
|
|
system:capture_17
|
|
alsa_pcm:hw:1,0:out18
|
|
system:capture_18
|
|
alsa_pcm:hw:1,0:out19
|
|
system:capture_19
|
|
alsa_pcm:hw:1,0:out20
|
|
system:capture_20
|
|
alsa_pcm:hw:1,0:out21
|
|
system:capture_21
|
|
alsa_pcm:hw:1,0:out22
|
|
system:capture_22
|
|
alsa_pcm:hw:1,0:out23
|
|
system:capture_23
|
|
alsa_pcm:hw:1,0:out24
|
|
system:capture_24
|
|
alsa_pcm:hw:1,0:out25
|
|
system:capture_25
|
|
alsa_pcm:hw:1,0:out26
|
|
system:capture_26
|
|
alsa_pcm:hw:1,0:out27
|
|
system:capture_27
|
|
alsa_pcm:hw:1,0:out28
|
|
system:capture_28
|
|
alsa_pcm:hw:1,0:out29
|
|
system:capture_29
|
|
alsa_pcm:hw:1,0:out30
|
|
system:capture_30
|
|
alsa_pcm:hw:1,0:out31
|
|
system:capture_31
|
|
alsa_pcm:hw:1,0:out32
|
|
system:capture_32
|
|
alsa_pcm:hw:1,0:out33
|
|
system:capture_33
|
|
alsa_pcm:hw:1,0:out34
|
|
system:capture_34
|
|
alsa_pcm:hw:1,0:out35
|
|
system:capture_35
|
|
alsa_pcm:hw:1,0:out36
|
|
system:capture_36
|
|
alsa_pcm:hw:1,0:in1
|
|
system:playback_1
|
|
alsa_pcm:hw:1,0:in2
|
|
system:playback_2
|
|
alsa_pcm:hw:1,0:in3
|
|
system:playback_3
|
|
alsa_pcm:hw:1,0:in4
|
|
system:playback_4
|
|
alsa_pcm:hw:1,0:in5
|
|
system:playback_5
|
|
alsa_pcm:hw:1,0:in6
|
|
system:playback_6
|
|
alsa_pcm:hw:1,0:in7
|
|
system:playback_7
|
|
alsa_pcm:hw:1,0:in8
|
|
system:playback_8
|
|
alsa_pcm:hw:1,0:in9
|
|
system:playback_9
|
|
alsa_pcm:hw:1,0:in10
|
|
system:playback_10
|
|
alsa_pcm:hw:1,0:in11
|
|
system:playback_11
|
|
alsa_pcm:hw:1,0:in12
|
|
system:playback_12
|
|
alsa_pcm:hw:1,0:in13
|
|
system:playback_13
|
|
alsa_pcm:hw:1,0:in14
|
|
system:playback_14
|
|
alsa_pcm:hw:1,0:in15
|
|
system:playback_15
|
|
alsa_pcm:hw:1,0:in16
|
|
system:playback_16
|
|
alsa_pcm:hw:1,0:in17
|
|
system:playback_17
|
|
alsa_pcm:hw:1,0:in18
|
|
system:playback_18
|
|
alsa_pcm:hw:1,0:in19
|
|
system:playback_19
|
|
alsa_pcm:hw:1,0:in20
|
|
system:playback_20
|
|
alsa_pcm:hw:1,0:in21
|
|
system:playback_21
|
|
alsa_pcm:hw:1,0:in22
|
|
system:playback_22
|
|
alsa_pcm:hw:1,0:in23
|
|
system:playback_23
|
|
alsa_pcm:hw:1,0:in24
|
|
system:playback_24
|
|
alsa_pcm:hw:1,0:in25
|
|
system:playback_25
|
|
alsa_pcm:hw:1,0:in26
|
|
system:playback_26
|
|
alsa_pcm:hw:1,0:in27
|
|
system:playback_27
|
|
alsa_pcm:hw:1,0:in28
|
|
system:playback_28
|
|
alsa_pcm:hw:1,0:in29
|
|
system:playback_29
|
|
alsa_pcm:hw:1,0:in30
|
|
system:playback_30
|
|
alsa_pcm:hw:1,0:in31
|
|
system:playback_31
|
|
alsa_pcm:hw:1,0:in32
|
|
system:playback_32
|
|
alsa_pcm:hw:1,0:in33
|
|
system:playback_33
|
|
alsa_pcm:hw:1,0:in34
|
|
system:playback_34
|
|
alsa_pcm:hw:1,0:in35
|
|
system:playback_35
|
|
alsa_pcm:hw:1,0:in36
|
|
system:playback_36
|