Pass full device name to audio/midi backends.

This commit is contained in:
Alexandre Ratchov 2015-12-09 11:13:11 +01:00
parent a04c34288e
commit 7530bbf6d2
11 changed files with 166 additions and 112 deletions

View File

@ -468,15 +468,24 @@ parsestr(const char *str, char *rstr, unsigned int max)
}
int
_aucat_open(struct aucat *hdl, const char *str, unsigned int mode,
unsigned int type)
_aucat_open(struct aucat *hdl, const char *str, unsigned int mode)
{
extern char *__progname;
int eof;
char host[NI_MAXHOST], opt[AMSG_OPTMAX];
const char *p = str;
unsigned int unit, devnum;
const char *p;
unsigned int unit, devnum, type;
if ((p = _sndio_parsetype(str, "snd")) != NULL)
type = 0;
else if ((p = _sndio_parsetype(str, "midithru")) != NULL)
type = 1;
else if ((p = _sndio_parsetype(str, "midi")) != NULL)
type = 2;
else {
DPRINTF("%s: unsupported device type\n", str);
return -1;
}
if (*p == '@') {
p = parsestr(++p, host, NI_MAXHOST);
if (p == NULL)
@ -489,7 +498,7 @@ _aucat_open(struct aucat *hdl, const char *str, unsigned int mode,
return 0;
} else
unit = 0;
if (*p != '/' && *p != ':') {
if (*p != '/') {
DPRINTF("%s: '/' expected\n", str);
return 0;
}

View File

@ -21,7 +21,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, unsigned);
int _aucat_open(struct aucat *, const char *, unsigned);
void _aucat_close(struct aucat *, int);
int _aucat_pollfd(struct aucat *, struct pollfd *, int);
int _aucat_revents(struct aucat *, struct pollfd *);

View File

@ -36,7 +36,6 @@ mio_open(const char *str, unsigned int mode, int nbio)
{
static char portany[] = MIO_PORTANY;
struct mio_hdl *hdl;
const char *p;
#ifdef DEBUG
_sndio_debug_init();
@ -51,32 +50,28 @@ mio_open(const char *str, unsigned int mode, int nbio)
str = portany;
}
if (strcmp(str, portany) == 0) {
hdl = _mio_aucat_open("/0", mode, nbio, 1);
hdl = _mio_aucat_open("midithru/0", mode, nbio);
if (hdl != NULL)
return hdl;
#if defined(USE_RMIDI)
return _mio_rmidi_open("/0", mode, nbio);
return _mio_rmidi_open("rmidi/0", mode, nbio);
#elif defined(USE_ALSA)
return mio_alsa_open("/0", mode, nbio);
return _mio_alsa_open("rmidi/0", mode, nbio);
#else
return NULL;
#endif
}
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, "midi")) != NULL)
return _mio_aucat_open(p, mode, nbio, 2);
#if defined(USE_RMIDI) || defined(USE_ALSA)
if ((p = _sndio_parsetype(str, "rmidi")) != NULL) {
#if defined(USE_SUN)
return _mio_rmidi_open(p, mode, nbio);
if (_sndio_parsetype(str, "snd") ||
_sndio_parsetype(str, "midithru") ||
_sndio_parsetype(str, "midi"))
return _mio_aucat_open(str, mode, nbio);
if (_sndio_parsetype(str, "rmidi"))
#if defined(USE_RMIDI)
return _mio_rmidi_open(str, mode, nbio);
#elif defined(USE_ALSA)
return mio_alsa_open(p, mode, nbio);
#endif
}
return _mio_alsa_open(str, mode, nbio);
#else
return NULL;
#endif
DPRINTF("mio_open: %s: unknown device type\n", str);
return NULL;

View File

@ -64,18 +64,24 @@ static struct mio_ops mio_alsa_ops = {
};
struct mio_hdl *
mio_alsa_open(const char *str, unsigned int mode, int nbio)
_mio_alsa_open(const char *_str, unsigned int mode, int nbio)
{
const char *p;
struct mio_alsa_hdl *hdl;
size_t len;
int rc;
switch (*str) {
p = _sndio_parsetype(_str, "rmidi");
if (p == NULL) {
DPRINTF("_mio_alsa_open: %s: \"rsnd\" expected\n", _str);
return NULL;
}
switch (*p) {
case '/':
str++;
p++;
break;
default:
DPRINTF("mio_alsa_open: %s: '/<devnum>' expected\n", str);
DPRINTF("_mio_alsa_open: %s: '/' expected\n", _str);
return NULL;
}
hdl = malloc(sizeof(struct mio_alsa_hdl));
@ -87,14 +93,14 @@ mio_alsa_open(const char *str, unsigned int mode, int nbio)
if (rc < 0)
DALSA("couldn't attach to stderr", rc);
#endif
len = strlen(str);
len = strlen(p);
hdl->devname = malloc(len + sizeof(DEVNAME_PREFIX));
if (hdl->devname == NULL) {
free(hdl);
return NULL;
}
memcpy(hdl->devname, DEVNAME_PREFIX, sizeof(DEVNAME_PREFIX) - 1);
memcpy(hdl->devname + sizeof(DEVNAME_PREFIX) - 1, str, len + 1);
memcpy(hdl->devname + sizeof(DEVNAME_PREFIX) - 1, p, len + 1);
hdl->in = hdl->out = NULL;
rc = snd_rawmidi_open(&hdl->in, &hdl->out,
hdl->devname, SND_RAWMIDI_NONBLOCK);

View File

@ -85,15 +85,14 @@ mio_aucat_runmsg(struct mio_aucat_hdl *hdl)
}
struct mio_hdl *
_mio_aucat_open(const char *str, unsigned int mode,
int nbio, unsigned int type)
_mio_aucat_open(const char *str, unsigned int mode, int nbio)
{
struct mio_aucat_hdl *hdl;
hdl = malloc(sizeof(struct mio_aucat_hdl));
if (hdl == NULL)
return NULL;
if (!_aucat_open(&hdl->aucat, str, mode, type))
if (!_aucat_open(&hdl->aucat, str, mode))
goto bad;
_mio_create(&hdl->mio, &mio_aucat_ops, mode, nbio);
if (!_aucat_setfl(&hdl->aucat, 1, &hdl->mio.eof))

View File

@ -45,9 +45,9 @@ struct mio_ops {
struct mio_hdl *_mio_rmidi_open(const char *, unsigned, int);
#ifdef USE_ALSA
struct mio_hdl *mio_alsa_open(const char *, unsigned, int);
struct mio_hdl *_mio_alsa_open(const char *, unsigned, int);
#endif
struct mio_hdl *_mio_aucat_open(const char *, unsigned, int, unsigned);
struct mio_hdl *_mio_aucat_open(const char *, unsigned, int);
void _mio_create(struct mio_hdl *, struct mio_ops *, unsigned, int);
void _mio_destroy(struct mio_hdl *);

View File

@ -15,6 +15,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef USE_RMIDI
#include <sys/types.h>
#include <sys/stat.h>
@ -56,33 +57,34 @@ static struct mio_ops mio_rmidi_ops = {
mio_rmidi_revents
};
struct mio_hdl *
_mio_rmidi_open(const char *str, unsigned int mode, int nbio)
static int
mio_rmidi_getfd(const char *str, unsigned int mode, int nbio)
{
int fd, flags;
struct mio_rmidi_hdl *hdl;
const char *p;
char path[DEVPATH_MAX];
unsigned int devnum;
int fd, flags;
switch (*str) {
p = _sndio_parsetype(str, "rmidi");
if (p == NULL) {
DPRINTF("mio_rmidi_getfd: %s: \"rsnd\" expected\n", str);
return -1;
}
switch (*p) {
case '/':
str++;
p++;
break;
default:
DPRINTF("_mio_rmidi_open: %s: '/<devnum>' expected\n", str);
return NULL;
DPRINTF("mio_rmidi_getfd: %s: '/' expected\n", str);
return -1;
}
str = _sndio_parsenum(str, &devnum, 255);
if (str == NULL || *str != '\0') {
DPRINTF("_mio_rmidi_open: can't determine device number\n");
return NULL;
p = _sndio_parsenum(p, &devnum, 255);
if (p == NULL || *p != '\0') {
DPRINTF("mio_rmidi_getfd: %s: number expected after '/'\n", str);
return -1;
}
hdl = malloc(sizeof(struct mio_rmidi_hdl));
if (hdl == NULL)
return NULL;
_mio_create(&hdl->mio, &mio_rmidi_ops, mode, nbio);
snprintf(path, sizeof(path), DEVPATH_PREFIX "%u", devnum);
if (mode == (MIO_OUT | MIO_IN))
if (mode == (MIO_IN | MIO_OUT))
flags = O_RDWR;
else
flags = (mode & MIO_OUT) ? O_WRONLY : O_RDONLY;
@ -90,12 +92,38 @@ _mio_rmidi_open(const char *str, unsigned int mode, int nbio)
if (errno == EINTR)
continue;
DPERROR(path);
goto bad_free;
return -1;
}
return fd;
}
static struct mio_hdl *
mio_rmidi_fdopen(int fd, unsigned int mode, int nbio)
{
struct mio_rmidi_hdl *hdl;
hdl = malloc(sizeof(struct mio_rmidi_hdl));
if (hdl == NULL)
return NULL;
_mio_create(&hdl->mio, &mio_rmidi_ops, mode, nbio);
hdl->fd = fd;
return (struct mio_hdl *)hdl;
bad_free:
free(hdl);
}
struct mio_hdl *
_mio_rmidi_open(const char *str, unsigned int mode, int nbio)
{
struct mio_hdl *hdl;
int fd;
fd = mio_rmidi_getfd(str, mode, nbio);
if (fd < 0)
return NULL;
hdl = mio_rmidi_fdopen(fd, mode, nbio);
if (hdl != NULL)
return hdl;
while (close(fd) < 0 && errno == EINTR)
; /* retry */
return NULL;
}
@ -173,3 +201,4 @@ mio_rmidi_revents(struct mio_hdl *sh, struct pollfd *pfd)
{
return pfd->revents;
}
#endif /* defined USE_RMIDI */

View File

@ -45,7 +45,6 @@ sio_open(const char *str, unsigned int mode, int nbio)
{
static char devany[] = SIO_DEVANY;
struct sio_hdl *hdl;
const char *p;
#ifdef DEBUG
_sndio_debug_init();
@ -60,29 +59,26 @@ sio_open(const char *str, unsigned int mode, int nbio)
str = devany;
}
if (strcmp(str, devany) == 0) {
hdl = _sio_aucat_open("/0", mode, nbio);
hdl = _sio_aucat_open("snd/0", mode, nbio);
if (hdl != NULL)
return hdl;
#if defined(USE_SUN)
return _sio_sun_open("/0", mode, nbio);
return _sio_sun_open("rsnd/0", mode, nbio);
#elif defined(USE_ALSA)
return _sio_alsa_open("/0", mode, nbio);
return _sio_alsa_open("rsnd/0", mode, nbio);
#else
return NULL;
#endif
}
if ((p = _sndio_parsetype(str, "snd")) != NULL ||
(p = _sndio_parsetype(str, "aucat")) != NULL)
return _sio_aucat_open(p, mode, nbio);
#if defined(USE_ALSA) || defined(USE_SUN)
if ((p = _sndio_parsetype(str, "rsnd")) != NULL ||
(p = _sndio_parsetype(str, "sun")) != NULL) {
if (_sndio_parsetype(str, "snd"))
return _sio_aucat_open(str, mode, nbio);
if (_sndio_parsetype(str, "rsnd"))
#if defined(USE_SUN)
return _sio_sun_open(p, mode, nbio);
return _sio_sun_open(str, mode, nbio);
#elif defined(USE_ALSA)
return _sio_alsa_open(p, mode, nbio);
#endif
}
return _sio_alsa_open(str, mode, nbio);
#else
return NULL;
#endif
DPRINTF("sio_open: %s: unknown device type\n", str);
return NULL;

View File

@ -275,17 +275,23 @@ sio_alsa_enctofmt(struct sio_alsa_hdl *hdl, snd_pcm_format_t *rfmt,
struct sio_hdl *
_sio_alsa_open(const char *str, unsigned mode, int nbio)
{
const char *p;
struct sio_alsa_hdl *hdl;
struct sio_par par;
size_t len;
int err;
switch (*str) {
p = _sndio_parsetype(str, "rsnd");
if (p == NULL) {
DPRINTF("_sio_alsa_open: %s: \"rsnd\" expected\n", str);
return NULL;
}
switch (*p) {
case '/':
str++;
p++;
break;
default:
DPRINTF("_sio_alsa_open: %s: '/<devnum>' expected\n", str);
DPRINTF("_sio_alsa_open: %s: '/' expected\n", str);
return NULL;
}
hdl = malloc(sizeof(struct sio_alsa_hdl));
@ -298,12 +304,12 @@ _sio_alsa_open(const char *str, unsigned mode, int nbio)
if (err < 0)
DALSA("couldn't attach to stderr", err);
#endif
len = strlen(str);
len = strlen(p);
hdl->devname = malloc(len + sizeof(DEVNAME_PREFIX));
if (hdl->devname == NULL)
goto bad_free_hdl;
memcpy(hdl->devname, DEVNAME_PREFIX, sizeof(DEVNAME_PREFIX) - 1);
memcpy(hdl->devname + sizeof(DEVNAME_PREFIX) - 1, str, len + 1);
memcpy(hdl->devname + sizeof(DEVNAME_PREFIX) - 1, p, len + 1);
if (mode & SIO_PLAY) {
err = snd_pcm_open(&hdl->opcm, hdl->devname,
SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);

View File

@ -156,7 +156,7 @@ _sio_aucat_open(const char *str, unsigned int mode, int nbio)
hdl = malloc(sizeof(struct sio_aucat_hdl));
if (hdl == NULL)
return NULL;
if (!_aucat_open(&hdl->aucat, str, mode, 0)) {
if (!_aucat_open(&hdl->aucat, str, mode)) {
free(hdl);
return NULL;
}

View File

@ -330,46 +330,57 @@ sio_sun_getcap(struct sio_hdl *sh, struct sio_cap *cap)
#undef NRATES
}
struct sio_hdl *
_sio_sun_open(const char *str, unsigned int mode, int nbio)
static int
sio_sun_getfd(const char *str, unsigned int mode, int nbio)
{
int fd, flags, fullduplex;
struct audio_info aui;
struct sio_sun_hdl *hdl;
struct sio_par par;
const char *p;
char path[DEVPATH_MAX];
unsigned int devnum;
int fd, flags;
switch (*str) {
p = _sndio_parsetype(str, "rsnd");
if (p == NULL) {
DPRINTF("sio_sun_getfd: %s: \"rsnd\" expected\n", str);
return -1;
}
switch (*p) {
case '/':
str++;
p++;
break;
default:
DPRINTF("_sio_sun_open: %s: '/<devnum>' expected\n", str);
return NULL;
DPRINTF("sio_sun_getfd: %s: '/' expected\n", str);
return -1;
}
str = _sndio_parsenum(str, &devnum, 255);
if (str == NULL || *str != '\0') {
DPRINTF("_sio_sun_open: can't determine device number\n");
return NULL;
p = _sndio_parsenum(p, &devnum, 255);
if (p == NULL || *p != '\0') {
DPRINTF("sio_sun_getfd: %s: number expected after '/'\n", str);
return -1;
}
hdl = malloc(sizeof(struct sio_sun_hdl));
if (hdl == NULL)
return NULL;
_sio_create(&hdl->sio, &sio_sun_ops, mode, nbio);
snprintf(path, sizeof(path), DEVPATH_PREFIX "%u", devnum);
if (mode == (SIO_PLAY | SIO_REC))
flags = O_RDWR;
else
flags = (mode & SIO_PLAY) ? O_WRONLY : O_RDONLY;
while ((fd = open(path, flags | O_NONBLOCK | O_CLOEXEC)) < 0) {
if (errno == EINTR)
continue;
DPERROR(path);
goto bad_free;
return -1;
}
return fd;
}
static struct sio_hdl *
sio_sun_fdopen(int fd, unsigned int mode, int nbio)
{
struct audio_info aui;
struct sio_sun_hdl *hdl;
struct sio_par par;
hdl = malloc(sizeof(struct sio_sun_hdl));
if (hdl == NULL)
return NULL;
_sio_create(&hdl->sio, &sio_sun_ops, mode, nbio);
/*
* pause the device
@ -381,18 +392,7 @@ _sio_sun_open(const char *str, unsigned int mode, int nbio)
aui.record.pause = 1;
if (ioctl(fd, AUDIO_SETINFO, &aui) < 0) {
DPERROR("sio_open_sun: setinfo");
goto bad_close;
}
/*
* If both play and record are requested then
* set full duplex mode.
*/
if (mode == (SIO_PLAY | SIO_REC)) {
fullduplex = 1;
if (ioctl(fd, AUDIO_SETFD, &fullduplex) < 0) {
DPRINTF("sio_open_sun: %s: can't set full-duplex\n", path);
goto bad_close;
}
goto bad_free;
}
hdl->fd = fd;
@ -410,16 +410,30 @@ _sio_sun_open(const char *str, unsigned int mode, int nbio)
par.bits = 16;
par.appbufsz = 1200;
if (!sio_setpar(&hdl->sio, &par))
goto bad_close;
goto bad_free;
return (struct sio_hdl *)hdl;
bad_close:
while (close(fd) < 0 && errno == EINTR)
; /* retry */
bad_free:
free(hdl);
return NULL;
}
struct sio_hdl *
_sio_sun_open(const char *str, unsigned int mode, int nbio)
{
struct sio_hdl *hdl;
int fd;
fd = sio_sun_getfd(str, mode, nbio);
if (fd < 0)
return NULL;
hdl = sio_sun_fdopen(fd, mode, nbio);
if (hdl != NULL)
return hdl;
while (close(fd) < 0 && errno == EINTR)
; /* retry */
return NULL;
}
static void
sio_sun_close(struct sio_hdl *sh)
{