summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libsndio/amsg.h8
-rw-r--r--lib/libsndio/aucat.c133
-rw-r--r--lib/libsndio/aucat.h2
-rw-r--r--lib/libsndio/debug.c16
-rw-r--r--lib/libsndio/debug.h11
-rw-r--r--lib/libsndio/mio.c34
-rw-r--r--lib/libsndio/mio_aucat.c6
-rw-r--r--lib/libsndio/mio_priv.h4
-rw-r--r--lib/libsndio/mio_rmidi.c11
-rw-r--r--lib/libsndio/sio.c42
-rw-r--r--lib/libsndio/sio_aucat.c8
-rw-r--r--lib/libsndio/sio_sun.c13
-rw-r--r--lib/libsndio/sndio.790
-rw-r--r--usr.bin/aucat/aucat.132
-rw-r--r--usr.bin/aucat/aucat.c39
-rw-r--r--usr.bin/aucat/dev.c68
-rw-r--r--usr.bin/aucat/dev.h5
-rw-r--r--usr.bin/aucat/opt.c39
-rw-r--r--usr.bin/aucat/opt.h4
-rw-r--r--usr.bin/aucat/sock.c14
20 files changed, 331 insertions, 248 deletions
diff --git a/lib/libsndio/amsg.h b/lib/libsndio/amsg.h
index 2cf7dd04e4b..585b1be8ce2 100644
--- a/lib/libsndio/amsg.h
+++ b/lib/libsndio/amsg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: amsg.h,v 1.3 2011/10/17 21:09:11 ratchov Exp $ */
+/* $OpenBSD: amsg.h,v 1.4 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -82,8 +82,10 @@ struct amsg {
uint16_t mode; /* bitmap of MODE_XXX */
#define AMSG_VERSION 5
uint8_t version; /* protocol version */
- uint8_t reserved1[5]; /* for future use */
- char opt[12]; /* profile name */
+ uint8_t devnum; /* device number */
+ uint32_t _reserved[1]; /* for future use */
+#define AMSG_OPTMAX 12
+ char opt[AMSG_OPTMAX]; /* profile name */
char who[12]; /* hint for leases */
} hello;
struct amsg_auth {
diff --git a/lib/libsndio/aucat.c b/lib/libsndio/aucat.c
index b7061ec3bd3..198b163e3a1 100644
--- a/lib/libsndio/aucat.c
+++ b/lib/libsndio/aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aucat.c,v 1.52 2011/10/22 10:23:44 ratchov Exp $ */
+/* $OpenBSD: aucat.c,v 1.53 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -149,7 +149,7 @@ aucat_rdata(struct aucat *hdl, void *buf, size_t len, int *eof)
hdl->rstate = RSTATE_MSG;
hdl->rtodo = sizeof(struct amsg);
}
- DPRINTF("aucat_rdata: read: n = %zd\n", n);
+ DPRINTFN(2, "aucat_rdata: read: n = %zd\n", n);
return n;
}
@@ -191,7 +191,7 @@ aucat_wdata(struct aucat *hdl, const void *buf, size_t len, unsigned wbpf, int *
}
return 0;
}
- DPRINTF("aucat_wdata: write: n = %zd\n", n);
+ DPRINTFN(2, "aucat_wdata: write: n = %zd\n", n);
hdl->wtodo -= n;
if (hdl->wtodo == 0) {
hdl->wstate = WSTATE_IDLE;
@@ -282,18 +282,13 @@ bad_gen:
}
int
-aucat_connect_tcp(struct aucat *hdl, char *host, char *unit)
+aucat_connect_tcp(struct aucat *hdl, char *host, unsigned unit)
{
int s, error, opt;
struct addrinfo *ailist, *ai, aihints;
- unsigned port;
char serv[NI_MAXSERV];
- if (sscanf(unit, "%u", &port) != 1) {
- DPRINTF("%s: bad unit number\n", unit);
- return 0;
- }
- snprintf(serv, sizeof(serv), "%u", port + AUCAT_PORT);
+ snprintf(serv, sizeof(serv), "%u", unit + AUCAT_PORT);
memset(&aihints, 0, sizeof(struct addrinfo));
aihints.ai_socktype = SOCK_STREAM;
aihints.ai_protocol = IPPROTO_TCP;
@@ -334,7 +329,7 @@ aucat_connect_tcp(struct aucat *hdl, char *host, char *unit)
}
int
-aucat_connect_un(struct aucat *hdl, char *unit)
+aucat_connect_un(struct aucat *hdl, unsigned unit)
{
struct sockaddr_un ca;
socklen_t len = sizeof(struct sockaddr_un);
@@ -343,7 +338,7 @@ aucat_connect_un(struct aucat *hdl, char *unit)
uid = geteuid();
snprintf(ca.sun_path, sizeof(ca.sun_path),
- "/tmp/aucat-%u/%s%s", uid, AUCAT_PATH, unit);
+ "/tmp/aucat-%u/%s%u", uid, AUCAT_PATH, unit);
ca.sun_family = AF_UNIX;
s = socket(AF_UNIX, SOCK_STREAM, 0);
if (s < 0)
@@ -354,7 +349,7 @@ aucat_connect_un(struct aucat *hdl, char *unit)
DPERROR(ca.sun_path);
/* try shared server */
snprintf(ca.sun_path, sizeof(ca.sun_path),
- "/tmp/aucat/%s%s", AUCAT_PATH, unit);
+ "/tmp/aucat/%s%u", AUCAT_PATH, unit);
while (connect(s, (struct sockaddr *)&ca, len) < 0) {
if (errno == EINTR)
continue;
@@ -368,43 +363,90 @@ aucat_connect_un(struct aucat *hdl, char *unit)
return 1;
}
+static const char *
+parsedev(const char *str, unsigned *rval)
+{
+ const char *p = str;
+ unsigned val;
+
+ for (val = 0; *p >= '0' && *p <= '9'; p++) {
+ val = 10 * val + (*p - '0');
+ if (val >= 16) {
+ DPRINTF("%s: number too large\n", str);
+ return NULL;
+ }
+ }
+ if (p == str) {
+ DPRINTF("%s: number expected\n", str);
+ return NULL;
+ }
+ *rval = val;
+ return p;
+}
+
+static const char *
+parsestr(const char *str, char *rstr, unsigned max)
+{
+ const char *p = str;
+
+ while (*p != '\0' && *p != ',' && *p != '/') {
+ if (--max == 0) {
+ DPRINTF("%s: string too long\n", str);
+ return NULL;
+ }
+ *rstr++ = *p++;
+ }
+ if (str == p) {
+ DPRINTF("%s: string expected\n", str);
+ return NULL;
+ }
+ *rstr = '\0';
+ return p;
+}
+
int
-aucat_open(struct aucat *hdl, const char *str, unsigned mode)
+aucat_open(struct aucat *hdl, const char *str, unsigned mode, unsigned type)
{
extern char *__progname;
- int eof, hashost;
- char unit[4], *sep, *opt;
- char host[NI_MAXHOST];
-
- if (str == NULL)
- str = "0";
- sep = strchr(str, '/');
- if (sep == NULL) {
- hashost = 0;
- } else {
- if (sep - str >= sizeof(host)) {
- DPRINTF("aucat_open: %s: host too long\n", str);
+ int eof;
+ char host[NI_MAXHOST], opt[AMSG_OPTMAX];
+ const char *p = str;
+ unsigned unit, devnum;
+
+ if (*p == '@') {
+ p = parsestr(++p, host, NI_MAXHOST);
+ if (p == NULL)
return 0;
- }
- memcpy(host, str, sep - str);
- host[sep - str] = '\0';
- hashost = 1;
- str = sep + 1;
- }
- sep = strchr(str, '.');
- if (sep == NULL) {
- opt = "default";
- strlcpy(unit, str, sizeof(unit));
- } else {
- opt = sep + 1;
- if (sep - str >= sizeof(unit)) {
- DPRINTF("aucat_init: %s: too long\n", str);
+ } else
+ *host = '\0';
+ if (*p == ',') {
+ p = parsedev(++p, &unit);
+ if (p == NULL)
return 0;
- }
- strlcpy(unit, str, opt - str);
+ } else
+ unit = 0;
+ if (*p != '/' && *p != ':') {
+ DPRINTF("%s: '/' expected\n", str);
+ return 0;
+ }
+ p = parsedev(++p, &devnum);
+ if (p == NULL)
+ return 0;
+ if (*p == '.') {
+ p = parsestr(++p, opt, AMSG_OPTMAX);
+ if (p == NULL)
+ return 0;
+ } else
+ strlcpy(opt, "default", AMSG_OPTMAX);
+ if (*p != '\0') {
+ DPRINTF("%s: junk at end of dev name\n", p);
+ return 0;
}
- DPRINTF("aucat_init: trying %s -> %s.%s\n", str, unit, opt);
- if (hashost) {
+ if (type)
+ devnum += 16; /* XXX */
+ DPRINTF("aucat_open: host=%s unit=%u devnum=%u opt=%s\n",
+ host, unit, devnum, opt);
+ if (host[0] != '\0') {
if (!aucat_connect_tcp(hdl, host, unit))
return 0;
} else {
@@ -434,6 +476,7 @@ aucat_open(struct aucat *hdl, const char *str, unsigned mode)
hdl->wmsg.cmd = htonl(AMSG_HELLO);
hdl->wmsg.u.hello.version = AMSG_VERSION;
hdl->wmsg.u.hello.mode = htons(mode);
+ hdl->wmsg.u.hello.devnum = devnum;
strlcpy(hdl->wmsg.u.hello.who, __progname,
sizeof(hdl->wmsg.u.hello.who));
strlcpy(hdl->wmsg.u.hello.opt, opt,
@@ -502,6 +545,6 @@ aucat_revents(struct aucat *hdl, struct pollfd *pfd)
{
int revents = pfd->revents;
- DPRINTF("aucat_revents: revents: %x\n", revents);
+ DPRINTFN(2, "aucat_revents: revents: %x\n", revents);
return revents;
}
diff --git a/lib/libsndio/aucat.h b/lib/libsndio/aucat.h
index 6598d70aadb..42dc89f85e7 100644
--- a/lib/libsndio/aucat.h
+++ b/lib/libsndio/aucat.h
@@ -20,7 +20,7 @@ int aucat_rmsg(struct aucat *, int *);
int aucat_wmsg(struct aucat *, int *);
size_t aucat_rdata(struct aucat *, void *, size_t, int *);
size_t aucat_wdata(struct aucat *, const void *, size_t, unsigned, int *);
-int aucat_open(struct aucat *, const char *, unsigned);
+int aucat_open(struct aucat *, const char *, unsigned, unsigned);
void aucat_close(struct aucat *, int);
int aucat_pollfd(struct aucat *, struct pollfd *, int);
int aucat_revents(struct aucat *, struct pollfd *);
diff --git a/lib/libsndio/debug.c b/lib/libsndio/debug.c
index 05431cc6b3e..b592506494d 100644
--- a/lib/libsndio/debug.c
+++ b/lib/libsndio/debug.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: debug.c,v 1.1 2011/04/16 10:52:22 ratchov Exp $ */
+/* $OpenBSD: debug.c,v 1.2 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2011 Alexandre Ratchov <alex@caoua.org>
*
@@ -39,3 +39,17 @@ sndio_debug_init(void)
}
}
#endif
+
+const char *
+sndio_parsetype(const char *str, char *type)
+{
+ while (*type) {
+ if (*type != *str)
+ return NULL;
+ type++;
+ str++;
+ }
+ if (*str >= 'a' && *str <= 'z')
+ return NULL;
+ return str;
+}
diff --git a/lib/libsndio/debug.h b/lib/libsndio/debug.h
index 53265f68550..4d3baf40eef 100644
--- a/lib/libsndio/debug.h
+++ b/lib/libsndio/debug.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: debug.h,v 1.1 2011/04/16 10:52:22 ratchov Exp $ */
+/* $OpenBSD: debug.h,v 1.2 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -20,6 +20,12 @@
#ifdef DEBUG
#include <stdio.h>
+#define DPRINTFN(n, ...) \
+ do { \
+ if (sndio_debug >= (n)) \
+ fprintf(stderr, __VA_ARGS__); \
+ } while(0)
+
#define DPRINTF(...) \
do { \
if (sndio_debug > 0) \
@@ -36,7 +42,10 @@ void sndio_debug_init(void);
extern int sndio_debug;
#else
#define DPRINTF(...) do {} while(0)
+#define DPRINTFN(...) do {} while(0)
#define DPERROR(s) do {} while(0)
#endif
+const char *sndio_parsetype(const char *, char *);
+
#endif
diff --git a/lib/libsndio/mio.c b/lib/libsndio/mio.c
index 55631863df3..c1d28ee9e54 100644
--- a/lib/libsndio/mio.c
+++ b/lib/libsndio/mio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mio.c,v 1.12 2011/10/17 21:09:11 ratchov Exp $ */
+/* $OpenBSD: mio.c,v 1.13 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -34,12 +34,8 @@
struct mio_hdl *
mio_open(const char *str, unsigned mode, int nbio)
{
- static char prefix_midithru[] = "midithru";
- static char prefix_rmidi[] = "rmidi";
- static char prefix_aucat[] = "aucat";
struct mio_hdl *hdl;
- char *sep;
- int len;
+ const char *p;
#ifdef DEBUG
sndio_debug_init();
@@ -49,26 +45,18 @@ mio_open(const char *str, unsigned mode, int nbio)
if (str == NULL && !issetugid())
str = getenv("MIDIDEVICE");
if (str == NULL) {
- hdl = mio_aucat_open("0", mode, nbio);
+ hdl = mio_aucat_open("/0", mode, nbio, 1);
if (hdl != NULL)
return hdl;
- return mio_rmidi_open("0", mode, nbio);
+ return mio_rmidi_open("/0", mode, nbio);
}
- sep = strchr(str, ':');
- if (sep == NULL) {
- DPRINTF("mio_open: %s: ':' missing in device name\n", str);
- return NULL;
- }
- len = sep - str;
- if (len == (sizeof(prefix_midithru) - 1) &&
- memcmp(str, prefix_midithru, len) == 0)
- return mio_aucat_open(sep + 1, mode, nbio);
- if (len == (sizeof(prefix_aucat) - 1) &&
- memcmp(str, prefix_aucat, len) == 0)
- return mio_aucat_open(sep + 1, mode, nbio);
- if (len == (sizeof(prefix_rmidi) - 1) &&
- memcmp(str, prefix_rmidi, len) == 0)
- return mio_rmidi_open(sep + 1, mode, nbio);
+ if ((p = sndio_parsetype(str, "snd")) != NULL ||
+ (p = sndio_parsetype(str, "aucat")) != NULL)
+ return mio_aucat_open(p, mode, nbio, 0);
+ if ((p = sndio_parsetype(str, "midithru")) != NULL)
+ return mio_aucat_open(p, mode, nbio, 1);
+ if ((p = sndio_parsetype(str, "rmidi")) != NULL)
+ return mio_rmidi_open(p, mode, nbio);
DPRINTF("mio_open: %s: unknown device type\n", str);
return NULL;
}
diff --git a/lib/libsndio/mio_aucat.c b/lib/libsndio/mio_aucat.c
index 5c2e55450fe..501fc95a258 100644
--- a/lib/libsndio/mio_aucat.c
+++ b/lib/libsndio/mio_aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mio_aucat.c,v 1.5 2011/10/17 21:09:11 ratchov Exp $ */
+/* $OpenBSD: mio_aucat.c,v 1.6 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -52,14 +52,14 @@ static struct mio_ops mio_aucat_ops = {
};
struct mio_hdl *
-mio_aucat_open(const char *str, unsigned mode, int nbio)
+mio_aucat_open(const char *str, unsigned mode, int nbio, unsigned type)
{
struct mio_aucat_hdl *hdl;
hdl = malloc(sizeof(struct mio_aucat_hdl));
if (hdl == NULL)
return NULL;
- if (!aucat_open(&hdl->aucat, str, mode))
+ if (!aucat_open(&hdl->aucat, str, mode, type))
goto bad;
mio_create(&hdl->mio, &mio_aucat_ops, mode, nbio);
if (!aucat_setfl(&hdl->aucat, nbio, &hdl->mio.eof))
diff --git a/lib/libsndio/mio_priv.h b/lib/libsndio/mio_priv.h
index dd22ca80bce..60efc2b7733 100644
--- a/lib/libsndio/mio_priv.h
+++ b/lib/libsndio/mio_priv.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mio_priv.h,v 1.7 2011/10/17 21:09:11 ratchov Exp $ */
+/* $OpenBSD: mio_priv.h,v 1.8 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -42,7 +42,7 @@ struct mio_ops {
};
struct mio_hdl *mio_rmidi_open(const char *, unsigned, int);
-struct mio_hdl *mio_aucat_open(const char *, unsigned, int);
+struct mio_hdl *mio_aucat_open(const char *, unsigned, int, unsigned);
void mio_create(struct mio_hdl *, struct mio_ops *, unsigned, int);
void mio_destroy(struct mio_hdl *);
diff --git a/lib/libsndio/mio_rmidi.c b/lib/libsndio/mio_rmidi.c
index b40584a0bfc..c638bf98ffd 100644
--- a/lib/libsndio/mio_rmidi.c
+++ b/lib/libsndio/mio_rmidi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mio_rmidi.c,v 1.9 2011/04/16 10:52:22 ratchov Exp $ */
+/* $OpenBSD: mio_rmidi.c,v 1.10 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -56,6 +56,15 @@ mio_rmidi_open(const char *str, unsigned mode, int nbio)
struct mio_rmidi_hdl *hdl;
char path[PATH_MAX];
+ switch (*str) {
+ case '/':
+ case ':': /* XXX: for backward compat */
+ str++;
+ break;
+ default:
+ DPRINTF("sio_sun_open: %s: '/<devnum>' expected\n", str);
+ return NULL;
+ }
hdl = malloc(sizeof(struct mio_rmidi_hdl));
if (hdl == NULL)
return NULL;
diff --git a/lib/libsndio/sio.c b/lib/libsndio/sio.c
index 1b1376c7d4f..65a94624300 100644
--- a/lib/libsndio/sio.c
+++ b/lib/libsndio/sio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sio.c,v 1.6 2011/05/09 17:34:14 ratchov Exp $ */
+/* $OpenBSD: sio.c,v 1.7 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -33,17 +33,6 @@
#define SIO_PAR_MAGIC 0x83b905a4
-struct sio_backend {
- char *prefix;
- struct sio_hdl *(*open)(const char *, unsigned, int);
-};
-
-static struct sio_backend backends[] = {
- { "aucat", sio_aucat_open },
- { "sun", sio_sun_open },
- { NULL, NULL }
-};
-
void
sio_initpar(struct sio_par *par)
{
@@ -54,10 +43,8 @@ sio_initpar(struct sio_par *par)
struct sio_hdl *
sio_open(const char *str, unsigned mode, int nbio)
{
- struct sio_backend *b;
struct sio_hdl *hdl;
- char *sep;
- int len;
+ const char *p;
#ifdef DEBUG
sndio_debug_init();
@@ -67,22 +54,17 @@ sio_open(const char *str, unsigned mode, int nbio)
if (str == NULL && !issetugid())
str = getenv("AUDIODEVICE");
if (str == NULL) {
- for (b = backends; b->prefix != NULL; b++) {
- hdl = b->open(NULL, mode, nbio);
- if (hdl != NULL)
- return hdl;
- }
- return NULL;
- }
- sep = strchr(str, ':');
- if (sep == NULL) {
- DPRINTF("sio_open: %s: ':' missing in device name\n", str);
- return NULL;
+ hdl = sio_aucat_open("/0", mode, nbio);
+ if (hdl != NULL)
+ return hdl;
+ return sio_sun_open("/", mode, nbio);
}
- len = sep - str;
- for (b = backends; b->prefix != NULL; b++) {
- if (strlen(b->prefix) == len && memcmp(b->prefix, str, len) == 0)
- return b->open(sep + 1, mode, nbio);
+ if ((p = sndio_parsetype(str, "snd")) != NULL ||
+ (p = sndio_parsetype(str, "aucat")) != NULL)
+ return sio_aucat_open(p, mode, nbio);
+ if ((p = sndio_parsetype(str, "rsnd")) != NULL ||
+ (p = sndio_parsetype(str, "sun")) != NULL) {
+ return sio_sun_open(p, mode, nbio);
}
DPRINTF("sio_open: %s: unknown device type\n", str);
return NULL;
diff --git a/lib/libsndio/sio_aucat.c b/lib/libsndio/sio_aucat.c
index 2fbdea23492..2a97b878930 100644
--- a/lib/libsndio/sio_aucat.c
+++ b/lib/libsndio/sio_aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sio_aucat.c,v 1.8 2011/10/17 21:09:11 ratchov Exp $ */
+/* $OpenBSD: sio_aucat.c,v 1.9 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -109,7 +109,7 @@ sio_aucat_runmsg(struct sio_aucat_hdl *hdl)
delta = ntohl(hdl->aucat.rmsg.u.ts.delta);
hdl->maxwrite += delta * hdl->wbpf;
hdl->delta += delta;
- DPRINTF("aucat: move = %d, delta = %d, maxwrite = %d\n",
+ DPRINTFN(2, "aucat: move = %d, delta = %d, maxwrite = %d\n",
delta, hdl->delta, hdl->maxwrite);
if (hdl->delta >= 0) {
sio_onmove_cb(&hdl->sio, hdl->delta);
@@ -156,7 +156,7 @@ sio_aucat_open(const char *str, unsigned mode, int nbio)
hdl = malloc(sizeof(struct sio_aucat_hdl));
if (hdl == NULL)
return NULL;
- if (!aucat_open(&hdl->aucat, str, mode)) {
+ if (!aucat_open(&hdl->aucat, str, mode, 0)) {
free(hdl);
return NULL;
}
@@ -466,7 +466,7 @@ sio_aucat_revents(struct sio_hdl *sh, struct pollfd *pfd)
}
if (hdl->sio.eof)
return POLLHUP;
- DPRINTF("sio_aucat_revents: %x\n", revents & hdl->events);
+ DPRINTFN(2, "sio_aucat_revents: %x\n", revents & hdl->events);
return revents & (hdl->events | POLLHUP);
}
diff --git a/lib/libsndio/sio_sun.c b/lib/libsndio/sio_sun.c
index 84e41f87d96..e02babc2117 100644
--- a/lib/libsndio/sio_sun.c
+++ b/lib/libsndio/sio_sun.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sio_sun.c,v 1.3 2011/05/03 20:15:23 ratchov Exp $ */
+/* $OpenBSD: sio_sun.c,v 1.4 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -343,8 +343,15 @@ sio_sun_open(const char *str, unsigned mode, int nbio)
struct sio_par par;
char path[PATH_MAX];
- if (str == NULL)
- str = "";
+ switch (*str) {
+ case '/':
+ case ':': /* XXX: for backward compat */
+ str++;
+ break;
+ default:
+ DPRINTF("sio_sun_open: %s: '/<devnum>' expected\n", str);
+ return NULL;
+ }
hdl = malloc(sizeof(struct sio_sun_hdl));
if (hdl == NULL)
return NULL;
diff --git a/lib/libsndio/sndio.7 b/lib/libsndio/sndio.7
index 98c58f2c357..6336cb6e739 100644
--- a/lib/libsndio/sndio.7
+++ b/lib/libsndio/sndio.7
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sndio.7,v 1.7 2011/10/18 07:07:25 jmc Exp $
+.\" $OpenBSD: sndio.7,v 1.8 2011/11/15 08:05:22 ratchov Exp $
.\"
.\" Copyright (c) 2007 Alexandre Ratchov <alex@caoua.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: October 18 2011 $
+.Dd $Mdocdate: November 15 2011 $
.Dt SNDIO 7
.Os
.Sh NAME
@@ -68,73 +68,77 @@ From the user's perspective every audio interface, MIDI port, and
.Xr aucat 1
service has a name of the form:
.Bd -literal -offset center
-type:[hostname/]unit[.option]
+type[@hostname][,unit]/devnum[.option]
.Ed
.Pp
This information is used by audio and MIDI applications to determine
how to access the audio device or MIDI port.
-.Bl -tag -width "option"
+.Bl -tag -width "hostname"
.It Pa type
The type of the audio device or MIDI port.
-Possible values for audio devices are
-.Pa aucat
-and
-.Pa sun ,
-corresponding to
-.Xr aucat 1
-sockets and hardware
+Possible values are:
+.Pp
+.Bl -tag -width "midithru" -offset 3n -compact
+.It Pa rsnd
+Raw
.Xr audio 4
-devices.
-Possible values for MIDI ports are
-.Pa aucat
-and
-.Pa rmidi
-corresponding to
-.Xr aucat 1
-software MIDI thru boxes or control ports and hardware
+device.
+.It Pa rmidi
+Raw
.Xr midi 4
-ports respectively.
+port.
+.It Pa snd
+Audio device exposed by
+.Xr aucat 1 .
+.It Pa midithru
+MIDI thru box created with
+.Xr aucat 1 .
+.El
.It Pa hostname
-The hostname where the remote
+The hostname or address where the remote
.Xr aucat 1
server to connect to is running.
.It Pa unit
+The number of the
+.Xr aucat 1
+server to connect to, corresponding to the integer specified using the
+.Fl U
+option of
+.Xr aucat 1 .
+Useful only if multiple
+.Xr aucat 1
+servers are running on the same system.
+.It Pa devnum
+Device number.
For hardware audio or MIDI ports, this corresponds to
the character device minor number.
For audio devices or MIDI ports created with
.Xr aucat 1
-it corresponds to the server
-.Em unit
-number, typically 0.
+it corresponds to the number of the corresponding
+.Fl fM
+option on the command line.
.It Pa option
-Corresponds to the profile string registered using the
+Corresponds to the sub-device string registered using the
.Fl s
option of
.Xr aucat 1 .
-Only meaningful for
-.Pa aucat
-device types.
.El
.Pp
For example:
.Pp
-.Bl -tag -width "aucat:0.rear" -offset 3n -compact
-.It Pa sun:0
+.Bl -tag -width "snd/0.rear" -offset 3n -compact
+.It Pa rsnd/0
First hardware audio device.
-.It Pa aucat:0
-Default audio device of the first
-.Xr aucat 1
-audio server.
-.It Pa aucat:0.rear
-First
-.Xr aucat 1
-server;
-device registered with
-.Fl s Fa rear .
-.It Pa rmidi:5
+.It Pa rmidi/5
Hardware MIDI port number 5.
-.It Pa aucat:0
-First software MIDI thru box or control port created with
+.It Pa snd/0
+First audio device exposed by
+.Xr aucat 1 .
+.It Pa snd/0.rear
+Sub-device registered with
+.Fl s Fa rear .
+.It Pa midithru/0
+First MIDI thru box created with
.Xr aucat 1 .
.El
.Sh AUTHENTICATION
diff --git a/usr.bin/aucat/aucat.1 b/usr.bin/aucat/aucat.1
index f6f85e9da41..7de491f11a1 100644
--- a/usr.bin/aucat/aucat.1
+++ b/usr.bin/aucat/aucat.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: aucat.1,v 1.91 2011/10/24 21:46:21 ratchov Exp $
+.\" $OpenBSD: aucat.1,v 1.92 2011/11/15 08:05:22 ratchov Exp $
.\"
.\" Copyright (c) 2006 Alexandre Ratchov <alex@caoua.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: October 24 2011 $
+.Dd $Mdocdate: November 15 2011 $
.Dt AUCAT 1
.Os
.Sh NAME
@@ -383,8 +383,8 @@ of both definitions are created.
The default
.Xr sndio 7
device is
-.Pa aucat:0
-.Pq also known as Pa aucat:0.default
+.Pa snd/0
+.Pq also known as Pa snd/0.default
.Pp
If
.Nm
@@ -572,29 +572,29 @@ are recommended:
.Pp
For instance, the following command will create two devices:
the default
-.Va aucat:0
+.Va snd/0
and a MIDI-controlled
-.Va aucat:0.mmc :
+.Va snd/0.mmc :
.Bd -literal -offset indent
$ aucat -l -r 48000 -z 400 -s default -t slave -s mmc
.Ed
.Pp
Streams connected to
-.Va aucat:0
+.Va snd/0
behave normally, while streams connected to
-.Va aucat:0.mmc
+.Va snd/0.mmc
wait for the MMC start signal and start synchronously.
Regardless of which device a stream is connected to,
its playback volume knob is exposed.
.Pp
For instance, the following command will play a file on the
-.Va aucat:0.mmc
+.Va snd/0.mmc
audio device, and give full control to MIDI software or hardware
connected to the
-.Va aucat:0.thru
+.Va snd/0.thru
MIDI port:
.Bd -literal -offset indent
-$ aucat -f aucat:0.mmc -t slave -q aucat:0.thru -i file.wav
+$ aucat -f snd/0.mmc -t slave -q midithru/0 -i file.wav
.Ed
.Pp
At this stage,
@@ -602,7 +602,7 @@ At this stage,
will start, stop and relocate automatically following all user
actions in the MIDI sequencer.
Note that the sequencer must use
-.Va aucat:0
+.Va snd/0
as the MTC source, i.e. the audio server, not the audio player.
.Sh ENVIRONMENT
.Bl -tag -width "AUCAT_COOKIE" -compact
@@ -639,9 +639,9 @@ Start
in server mode using default parameters, creating an
additional sub-device for output to channels 2:3 only (rear speakers
on most cards), exposing the
-.Pa aucat:0
+.Pa snd/0
and
-.Pa aucat:0.rear
+.Pa snd/0.rear
devices:
.Bd -literal -offset indent
$ aucat -l -s default -c 2:3 -s rear
@@ -651,9 +651,9 @@ Start
.Nm
in server mode, creating the default sub-device with low volume and
an additional sub-device for high volume output, exposing the
-.Pa aucat:0
+.Pa snd/0
and
-.Pa aucat:0.max
+.Pa snd/0.max
devices:
.Bd -literal -offset indent
$ aucat -l -v 65 -s default -v 127 -s max
diff --git a/usr.bin/aucat/aucat.c b/usr.bin/aucat/aucat.c
index 4031b37d1b3..ce80ccad1b5 100644
--- a/usr.bin/aucat/aucat.c
+++ b/usr.bin/aucat/aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aucat.c,v 1.124 2011/10/18 21:04:26 ratchov Exp $ */
+/* $OpenBSD: aucat.c,v 1.125 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -71,6 +71,13 @@
#define DEFAULT_ROUND (44100 / 15)
#endif
+/*
+ * default device in server mode
+ */
+#ifndef DEFAULT_DEV
+#define DEFAULT_DEV "rsnd/0"
+#endif
+
#ifdef DEBUG
volatile sig_atomic_t debug_level = 1;
#endif
@@ -337,7 +344,10 @@ mkdev(char *path, int mode, int bufsz, int round, int hold, int autovol)
bufsz = round * 4;
} else if (!round)
round = bufsz / 4;
- return dev_new(path, mode, bufsz, round, hold, autovol);
+ d = dev_new(path, mode, bufsz, round, hold, autovol);
+ if (d == NULL)
+ exit(1);
+ return d;
}
struct opt *
@@ -537,20 +547,25 @@ main(int argc, char **argv)
fputs(usagestr, stderr);
exit(1);
}
- if (wav_list == NULL) {
- if (opt_list == NULL) {
- d = mkdev(NULL, 0, bufsz, round, 1, autovol);
- mkopt("default", d, &rpar, &ppar,
- mode, vol, mmc, join);
- server = 1;
- }
- } else {
- d = mkdev(NULL, 0, bufsz, round, 1, autovol);
- if ((d->reqmode & MODE_THRU) && !d->ctl_list) {
+ if (wav_list) {
+ if (server)
+ errx(1, "-io not allowed in server mode");
+ if ((d = dev_list) && d->next)
+ errx(1, "only one device allowed in non-server mode");
+ if ((d->reqmode & MODE_THRU) && d->ctl_list == NULL) {
if (!devctl_add(d, "default", MODE_MIDIMASK))
errx(1, "%s: can't open port", optarg);
d->reqmode |= MODE_MIDIMASK;
}
+ } else {
+ if (dev_list == NULL)
+ mkdev(DEFAULT_DEV, 0, bufsz, round, hold, autovol);
+ for (d = dev_list; d != NULL; d = d->next) {
+ if (opt_byname("default", d->num))
+ continue;
+ mkopt("default", d, &rpar, &ppar, mode, vol, mmc, join);
+ server = 1;
+ }
}
if (server) {
getbasepath(base, sizeof(base));
diff --git a/usr.bin/aucat/dev.c b/usr.bin/aucat/dev.c
index 449898b1078..90e0a6bd31b 100644
--- a/usr.bin/aucat/dev.c
+++ b/usr.bin/aucat/dev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dev.c,v 1.67 2011/10/12 07:20:04 ratchov Exp $ */
+/* $OpenBSD: dev.c,v 1.68 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -62,27 +62,6 @@
* finished draining), then the device
* automatically switches to INIT or CLOSED
*/
-/*
- * TODO:
- *
- * priming buffer is not ok, because it will insert silence and
- * break synchronization to other programs.
- *
- * priming buffer in server mode is required, because f->bufsz may
- * be smaller than the server buffer and may cause underrun in the
- * dev_bufsz part of the buffer, in turn causing apps to break. It
- * doesn't hurt because we care only in synchronization between
- * clients.
- *
- * Priming is not required in non-server mode, because streams
- * actually start when they are in the READY state, and their
- * buffer is large enough to never cause underruns of dev_bufsz.
- *
- * Fix sock.c to allocate dev_bufsz, but to use only appbufsz --
- * or whatever -- but to avoid underruns in dev_bufsz. Then remove
- * this ugly hack.
- *
- */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -108,6 +87,21 @@ void dev_clear(struct dev *);
int devctl_open(struct dev *, struct devctl *);
struct dev *dev_list = NULL;
+unsigned dev_sndnum = 0, dev_thrnum = 0;
+
+#ifdef DEBUG
+void
+dev_dbg(struct dev *d)
+{
+ if (d->num >= DEV_NMAX) {
+ dbg_puts("thr");
+ dbg_putu(d->num - DEV_NMAX);
+ } else {
+ dbg_puts("snd");
+ dbg_putu(d->num);
+ }
+}
+#endif
/*
* Create a sndio device
@@ -117,12 +111,24 @@ dev_new(char *path, unsigned mode,
unsigned bufsz, unsigned round, unsigned hold, unsigned autovol)
{
struct dev *d;
+ unsigned *pnum;
d = malloc(sizeof(struct dev));
if (d == NULL) {
perror("malloc");
exit(1);
}
+ pnum = (mode & MODE_THRU) ? &dev_thrnum : &dev_sndnum;
+ if (*pnum == DEV_NMAX) {
+#ifdef DEBUG
+ if (debug_level >= 1)
+ dbg_puts("too many devices\n");
+#endif
+ return NULL;
+ }
+ d->num = (*pnum)++;
+ if (mode & MODE_THRU)
+ d->num += DEV_NMAX;
d->ctl_list = NULL;
d->path = path;
d->reqmode = mode;
@@ -135,7 +141,7 @@ dev_new(char *path, unsigned mode,
d->autostart = 0;
d->pstate = DEV_CLOSED;
d->next = dev_list;
- dev_list = d;
+ dev_list = d;
return d;
}
@@ -161,7 +167,7 @@ dev_init(struct dev *d)
{
if ((d->reqmode & (MODE_AUDIOMASK | MODE_MIDIMASK)) == 0) {
#ifdef DEBUG
- dbg_puts(d->path);
+ dev_dbg(d);
dbg_puts(": has no streams, skipped\n");
#endif
return 1;
@@ -177,7 +183,7 @@ dev_init(struct dev *d)
* Add a MIDI port to the device
*/
int
-devctl_add(struct dev *d, char *name, unsigned mode)
+devctl_add(struct dev *d, char *path, unsigned mode)
{
struct devctl *c;
@@ -186,7 +192,7 @@ devctl_add(struct dev *d, char *name, unsigned mode)
perror("malloc");
exit(1);
}
- c->path = name;
+ c->path = path;
c->mode = mode;
c->next = d->ctl_list;
d->ctl_list = c;
@@ -283,6 +289,8 @@ dev_open(struct dev *d)
if (f == NULL) {
#ifdef DEBUG
if (debug_level >= 1) {
+ dev_dbg(d);
+ dbg_puts(": ");
dbg_puts(d->path);
dbg_puts(": failed to open audio device\n");
}
@@ -296,7 +304,7 @@ dev_open(struct dev *d)
if ((d->mode & (MODE_PLAY | MODE_REC)) == 0) {
#ifdef DEBUG
if (debug_level >= 1) {
- dbg_puts(d->path);
+ dev_dbg(d);
dbg_puts(": mode not supported by device\n");
}
#endif
@@ -356,13 +364,13 @@ dev_open(struct dev *d)
#ifdef DEBUG
if (debug_level >= 2) {
if (d->mode & MODE_REC) {
- dbg_puts(d->path);
+ dev_dbg(d);
dbg_puts(": recording ");
aparams_dbg(&d->ipar);
dbg_puts("\n");
}
if (d->mode & MODE_PLAY) {
- dbg_puts(d->path);
+ dev_dbg(d);
dbg_puts(": playing ");
aparams_dbg(&d->opar);
dbg_puts("\n");
@@ -471,7 +479,7 @@ dev_open(struct dev *d)
#ifdef DEBUG
if (debug_level >= 2) {
if (d->mode & (MODE_PLAY | MODE_RECMASK)) {
- dbg_puts(d->path);
+ dev_dbg(d);
dbg_puts(": block size is ");
dbg_putu(d->round);
dbg_puts(" frames, using ");
diff --git a/usr.bin/aucat/dev.h b/usr.bin/aucat/dev.h
index e191a74fb57..a572401d9db 100644
--- a/usr.bin/aucat/dev.h
+++ b/usr.bin/aucat/dev.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dev.h,v 1.30 2011/10/12 07:20:04 ratchov Exp $ */
+/* $OpenBSD: dev.h,v 1.31 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -37,6 +37,8 @@ struct dev {
unsigned autovol; /* auto adjust playvol ? */
unsigned autostart; /* don't wait for MMC start */
unsigned refcnt; /* number of openers */
+#define DEV_NMAX 16 /* max number of devices */
+ unsigned num; /* serial number */
#define DEV_CLOSED 0 /* closed */
#define DEV_INIT 1 /* stopped */
#define DEV_START 2 /* ready to start */
@@ -62,6 +64,7 @@ struct dev {
extern struct dev *dev_list;
+void dev_dbg(struct dev *);
int dev_init(struct dev *);
int dev_run(struct dev *);
int dev_ref(struct dev *);
diff --git a/usr.bin/aucat/opt.c b/usr.bin/aucat/opt.c
index d3a3e993a95..6bcf22b052c 100644
--- a/usr.bin/aucat/opt.c
+++ b/usr.bin/aucat/opt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: opt.c,v 1.11 2011/10/12 07:20:04 ratchov Exp $ */
+/* $OpenBSD: opt.c,v 1.12 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -28,7 +28,8 @@
struct opt *opt_list = NULL;
struct opt *
-opt_new(char *name, struct dev *dev, struct aparams *wpar, struct aparams *rpar,
+opt_new(char *name, struct dev *dev,
+ struct aparams *wpar, struct aparams *rpar,
int maxweight, int mmc, int join, unsigned mode)
{
struct opt *o, **po;
@@ -41,10 +42,8 @@ opt_new(char *name, struct dev *dev, struct aparams *wpar, struct aparams *rpar,
exit(1);
}
c = name[len];
- if (c < 'a' && c > 'z' &&
- c < 'A' && c > 'Z' &&
- c < '0' && c > '9' &&
- c != '_') {
+ if ((c < 'a' || c > 'z') &&
+ (c < 'A' || c > 'Z')) {
fprintf(stderr, "%s: '%c' not allowed\n", name, c);
exit(1);
}
@@ -54,7 +53,6 @@ opt_new(char *name, struct dev *dev, struct aparams *wpar, struct aparams *rpar,
perror("opt_new: malloc");
exit(1);
}
- memcpy(o->name, name, len + 1);
if (mode & MODE_RECMASK)
o->wpar = (mode & MODE_MON) ? *rpar : *wpar;
if (mode & MODE_PLAY)
@@ -64,8 +62,10 @@ opt_new(char *name, struct dev *dev, struct aparams *wpar, struct aparams *rpar,
o->join = join;
o->mode = mode;
o->dev = dev;
+ memcpy(o->name, name, len + 1);
for (po = &opt_list; *po != NULL; po = &(*po)->next) {
- if (strcmp(o->name, (*po)->name) == 0) {
+ if (o->dev->num == (*po)->dev->num &&
+ strcmp(o->name, (*po)->name) == 0) {
fprintf(stderr, "%s: already defined\n", o->name);
exit(1);
}
@@ -74,9 +74,9 @@ opt_new(char *name, struct dev *dev, struct aparams *wpar, struct aparams *rpar,
*po = o;
#ifdef DEBUG
if (debug_level >= 2) {
+ dev_dbg(o->dev);
+ dbg_puts(".");
dbg_puts(o->name);
- dbg_puts("@");
- dbg_puts(o->dev->path);
dbg_puts(":");
if (o->mode & MODE_REC) {
dbg_puts(" rec=");
@@ -115,27 +115,16 @@ opt_new(char *name, struct dev *dev, struct aparams *wpar, struct aparams *rpar,
}
struct opt *
-opt_byname(char *name)
+opt_byname(char *name, unsigned num)
{
struct opt *o;
for (o = opt_list; o != NULL; o = o->next) {
- if (strcmp(name, o->name) == 0) {
-#ifdef DEBUG
- if (debug_level >= 3) {
- dbg_puts(o->name);
- dbg_puts(": option found\n");
- }
-#endif
+ if (o->dev->num != num)
+ continue;
+ if (strcmp(name, o->name) == 0)
return o;
- }
- }
-#ifdef DEBUG
- if (debug_level >= 3) {
- dbg_puts(name);
- dbg_puts(": option not found\n");
}
-#endif
return NULL;
}
diff --git a/usr.bin/aucat/opt.h b/usr.bin/aucat/opt.h
index c904fbbb9fa..adbbba392ec 100644
--- a/usr.bin/aucat/opt.h
+++ b/usr.bin/aucat/opt.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: opt.h,v 1.10 2011/10/12 07:20:04 ratchov Exp $ */
+/* $OpenBSD: opt.h,v 1.11 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -40,6 +40,6 @@ extern struct opt *opt_list;
struct opt *opt_new(char *, struct dev *, struct aparams *, struct aparams *,
int, int, int, unsigned);
int opt_bind(struct opt *);
-struct opt *opt_byname(char *);
+struct opt *opt_byname(char *, unsigned);
#endif /* !defined(OPT_H) */
diff --git a/usr.bin/aucat/sock.c b/usr.bin/aucat/sock.c
index cab30a989e3..9bef95065a2 100644
--- a/usr.bin/aucat/sock.c
+++ b/usr.bin/aucat/sock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sock.c,v 1.60 2011/06/03 16:22:34 ratchov Exp $ */
+/* $OpenBSD: sock.c,v 1.61 2011/11/15 08:05:22 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -1033,9 +1033,19 @@ sock_hello(struct sock *f)
#endif
return 0;
}
- f->opt = opt_byname(p->opt);
+ f->opt = opt_byname(p->opt, AMSG_ISSET(p->devnum) ? p->devnum : 0);
if (f->opt == NULL)
return 0;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": using ");
+ dev_dbg(f->opt->dev);
+ dbg_puts(".");
+ dbg_puts(f->opt->name);
+ dbg_puts("\n");
+ }
+#endif
if (!dev_ref(f->opt->dev))
return 0;
if ((mode & MODE_REC) && (f->opt->mode & MODE_MON)) {