diff --git a/README.TXT b/README.TXT index 20b6c4f..c8851d6 100644 --- a/README.TXT +++ b/README.TXT @@ -19,8 +19,12 @@ Notes: The asio.c file uses 32 bit integer buffers, wich is supported by most asio applications. The asio.c.float uses 32 bit float buffers and thus avoids the format conversion necessary for jack. -You can set the number of ASIO inputs/outputs using evnironment variables + +Runtime settings +---------------- + +You can set the number of ASIO inputs/outputs using environment variables ASIO_INPUTS ASIO_OUTPUTS @@ -28,13 +32,28 @@ with bash e.g.: export ASIO_INPUTS=4 export ASIO_OUTPUTS=8 +You can set the connections for the ports using environment variables +INPORTn=client:port +OUTPORTn=client:port +where "n" is the wine port number, starting at zero and the "client:port" +is the JACK port you want to use. These are used to override physical ports +that would otherwise be used. + +Rather than setting these in your environment, you can set up a file called +.wineasiocfg in your home directory (or a site-wide /etc/default/wineasiocfg). + +---------------- + original code: Robert Reif posted to the wine mailinglist modified by: Ralf Beck (musical_snake@gmx.de) +port mapping and config file: Peter L Jones (pljones@users.sf.net) todo: - make timecode sync to jack transport changelog: +0.5: +03-SEP-2007: port mapping and config file 0.3: 30-APR-2007: corrected connection of in/outputs diff --git a/asio.c b/asio.c index 0c767fc..3f77799 100644 --- a/asio.c +++ b/asio.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2006 Robert Reif + * Portions copyright (C) 2007 Peter L Jones * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,6 +20,8 @@ #include "config.h" #include "port.h" +#include "settings.h" + //#include #include #include @@ -260,6 +263,8 @@ WRAP_THISCALL( ASIOBool __stdcall, IWineASIOImpl_init, (LPWINEASIO iface, void * int i,j; char *envi; char name[32]; + char *usercfg = NULL; + FILE *cfg; This.sample_rate = 48000.0; This.block_frames = 1024; @@ -293,10 +298,49 @@ WRAP_THISCALL( ASIOBool __stdcall, IWineASIOImpl_init, (LPWINEASIO iface, void * TRACE("sample rate: %f\n", This.sample_rate); - envi = getenv("ASIO_INPUTS"); + if (asprintf(&usercfg, "%s/%s", getenv("HOME"), USERCFG) >= 0) + { + cfg = fopen(usercfg, "r"); + TRACE("Config: %s\n", usercfg); + free(usercfg); + } else cfg = NULL; + if (cfg == NULL) + { + cfg = fopen(SITECFG, "r"); + if (cfg) TRACE("Config: %s\n", SITECFG); + } + if (cfg) + { + char *line = NULL; + size_t len = 0; + ssize_t read; + while( (read = getline(&line, &len, cfg)) != -1) + { + while (isspace(line[--read])) line[read]='\0'; + if ((strstr(line, ENV_INPUTS) == line + || strstr(line, ENV_OUTPUTS) == line + || strstr(line, MAP_INPORT) == line + || strstr(line, MAP_OUTPORT) == line) + && strchr(line, '=')) + { + TRACE("env: '%s'\n", line); + putenv(line); + } + else + { + free(line); + } + line = NULL; + len = 0; + } + + fclose(cfg); + } + + envi = getenv(ENV_INPUTS); if (envi != NULL) MAX_INPUTS = atoi(envi); - envi = getenv("ASIO_OUTPUTS"); + envi = getenv(ENV_OUTPUTS); if (envi != NULL) MAX_OUTPUTS = atoi(envi); // initialize input buffers @@ -377,7 +421,10 @@ WRAP_THISCALL( void __stdcall, IWineASIOImpl_getErrorMessage, (LPWINEASIO iface, WRAP_THISCALL( ASIOError __stdcall, IWineASIOImpl_start, (LPWINEASIO iface)) { + char *var_port = NULL; + char *val_port = NULL; const char ** ports; + int numports; int i; if (This.callbacks) @@ -393,39 +440,50 @@ WRAP_THISCALL( ASIOError __stdcall, IWineASIOImpl_start, (LPWINEASIO iface)) } ports = fp_jack_get_ports(This.client, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); + for(numports = 0; ports && ports[numports]; numports++); - if (ports) + for (i = 0; i < MAX_INPUTS; i++) { + asprintf(&var_port, "%s%d", MAP_INPORT, i); + val_port = getenv(var_port); + TRACE("%d: %s %s\n", i, var_port, val_port); + free(var_port); + var_port = NULL; + + if (This.input[i].active == ASIOTrue && (val_port || i < numports)) + if (fp_jack_connect(This.client, + val_port ? val_port : ports[i], + fp_jack_port_name(This.input[i].port))) + { + WARN("input %d connect failed\n", i); + } + } - for (i = 0; i < MAX_INPUTS && ports[i]; i++) - { - if (This.input[i].active == ASIOTrue) - if (fp_jack_connect(This.client, ports[i], fp_jack_port_name(This.input[i].port))) - { - WARN("input %d connect failed\n", i); - } - } - + if (ports) free(ports); - } ports = fp_jack_get_ports(This.client, NULL, NULL, JackPortIsPhysical | JackPortIsInput); + for(numports = 0; ports && ports[numports]; numports++); - if (ports) + for (i = 0; (i < MAX_OUTPUTS); i++) { - - for (i = 0; (i < MAX_OUTPUTS) && ports[i]; i++) - { + asprintf(&var_port, "%s%d", MAP_OUTPORT, i); + val_port = getenv(var_port); + TRACE("%d: %s %s\n", i, var_port, val_port); + free(var_port); + var_port = NULL; - if (This.output[i].active == ASIOTrue) - if (fp_jack_connect(This.client, fp_jack_port_name(This.output[i].port), ports[i])) - { + if (This.output[i].active == ASIOTrue && (val_port || i < numports)) + if (fp_jack_connect(This.client, + fp_jack_port_name(This.output[i].port), + val_port ? val_port : ports[i])) + { WARN("output %d connect failed\n", i); - } - } + } + } + if (ports) free(ports); - } This.state = Run; TRACE("started\n"); diff --git a/settings.h b/settings.h new file mode 100644 index 0000000..e92a328 --- /dev/null +++ b/settings.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2007 Peter L Jones + * Ugh, can you really copyright something this trivial? + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +static const char* ENV_INPUTS = "ASIO_INPUTS"; +static const char* ENV_OUTPUTS = "ASIO_OUTPUTS"; +static const char* USERCFG = ".wineasiocfg"; +static const char* SITECFG = "/etc/default/wineasiocfg"; +static const char* MAP_INPORT = "INPORT"; +static const char* MAP_OUTPORT = "OUTPORT";