make -a apply on MIDI ports

This commit is contained in:
Alexandre Ratchov 2011-06-20 17:53:09 +02:00
parent 9429404049
commit 007a5ce2e1
7 changed files with 147 additions and 59 deletions

View File

@ -74,15 +74,18 @@ The options are as follows:
.It Fl a Ar flag
Control whether
.Nm
opens the audio device only when needed or keeps it open all the time.
opens the audio device
.Pq Fl f
or the MIDI port
.Pq Fl q
only when needed or keeps it open all the time.
If the flag is
.Va on
then the device is kept open all the time, ensuring no other program can
steal it.
then it is kept open all the time, ensuring no other program can steal it.
If the flag is
.Va off ,
then it's automatically closed, allowing other programs to have direct
access to the device, or the device to be disconnected.
access to it, or corresponding audio or MIDI hardware to be disconnected.
The default is
.Va on .
.It Fl b Ar nframes
@ -319,7 +322,7 @@ On the command line,
per-device parameters
.Pq Fl abwz
must precede the device definition
.Pq Fl f ,
.Pq Fl fq ,
and per-stream parameters
.Pq Fl Ccehjmrtvx
must precede the stream definition

View File

@ -235,6 +235,7 @@ SLIST_HEAD(cfstrlist, cfstr);
struct cfmid {
SLIST_ENTRY(cfmid) entry;
char *path; /* static path (no need to copy it) */
int hold;
};
SLIST_HEAD(cfmidlist, cfmid);
@ -338,16 +339,28 @@ cfstr_add(struct cfstrlist *list, struct cfstr *cs, char *path)
SLIST_INSERT_HEAD(list, cs, entry);
}
void
cfmid_add(struct cfmidlist *list, char *path)
struct cfmid *
cfmid_new(struct cfmid *templ)
{
struct cfmid *cm;
cm = malloc(sizeof(struct cfmid));
if (cm == NULL) {
perror("malloc");
abort();
}
if (templ)
memcpy(cm, templ, sizeof(struct cfmid));
else {
cm->hold = 1;
}
cm->path = NULL;
return cm;
}
void
cfmid_add(struct cfmidlist *list, struct cfmid *cm, char *path)
{
cm->path = path;
SLIST_INSERT_HEAD(list, cm, entry);
}
@ -506,6 +519,7 @@ aucat_main(int argc, char **argv)
*/
cd = cfdev_new(NULL);
cs = cfstr_new(NULL);
cm = cfmid_new(NULL);
while ((c = getopt(argc, argv, "a:w:dnb:c:C:e:r:h:x:v:i:o:f:m:luq:s:U:L:t:j:z:")) != -1) {
switch (c) {
@ -587,13 +601,14 @@ aucat_main(int argc, char **argv)
nsock++;
break;
case 'a':
cd->hold = opt_onoff();
cm->hold = cd->hold = opt_onoff();
break;
case 'w':
cd->autovol = opt_onoff();
break;
case 'q':
cfmid_add(&cd->mids, optarg);
cfmid_add(&cd->mids, cm, optarg);
cm = cfmid_new(cm);
break;
case 'b':
cd->bufsz = strtonum(optarg, 1, RATE_MAX * 5, &str);
@ -673,6 +688,7 @@ aucat_main(int argc, char **argv)
free(cs);
free(cd);
}
free(cm);
/*
* Check modes and calculate "best" device parameters. Iterate over all
@ -752,8 +768,8 @@ aucat_main(int argc, char **argv)
while (!SLIST_EMPTY(&cd->mids)) {
cm = SLIST_FIRST(&cd->mids);
SLIST_REMOVE_HEAD(&cd->mids, entry);
if (!dev_thruadd(d, cm->path, 1, 1))
errx(1, "%s: can't open device", cm->path);
if (!devctl_add(d, cm->path, cm->hold, MODE_MIDIMASK))
errx(1, "%s: can't open port", cm->path);
free(cm);
}
@ -870,8 +886,9 @@ aucat_main(int argc, char **argv)
void
midicat_usage(void)
{
(void)fputs("usage: " PROG_MIDICAT " [-dl] "
"[-i file] [-L addr] [-o file] [-q port] [-s name] [-U unit]\n",
(void)fputs("usage: " PROG_MIDICAT " [-dl] [-a flag] "
"[-i file] [-L addr] [-o file] [-q port]\n\t"
"[-s name] [-U unit]\n",
stderr);
}
@ -908,8 +925,9 @@ midicat_main(int argc, char **argv)
*/
cs = cfstr_new(NULL);
cd = cfdev_new(NULL);
cm = cfmid_new(NULL);
while ((c = getopt(argc, argv, "di:o:ls:q:U:L:")) != -1) {
while ((c = getopt(argc, argv, "di:o:ls:a:q:U:L:")) != -1) {
switch (c) {
case 'd':
#ifdef DEBUG
@ -926,8 +944,12 @@ midicat_main(int argc, char **argv)
cfstr_add(&cd->outs, cs, optarg);
cs = cfstr_new(cs);
break;
case 'a':
cm->hold = opt_onoff();
break;
case 'q':
cfmid_add(&cd->mids, optarg);
cfmid_add(&cd->mids, cm, optarg);
cm = cfmid_new(cm);
break;
case 's':
cfstr_add(&cd->opts, cs, optarg);
@ -978,15 +1000,19 @@ midicat_main(int argc, char **argv)
if (SLIST_EMPTY(&cd->mids)) {
if (SLIST_EMPTY(&cd->ins) && SLIST_EMPTY(&cd->outs)) {
cfstr_add(&cd->opts, cs, DEFAULT_OPT);
free(cm);
nsock++;
} else {
cfmid_add(&cd->mids, "default");
cfmid_add(&cd->mids, cm, "default");
free(cs);
}
} else
} else {
free(cm);
free(cs);
}
cfdev_add(&cfdevs, cd, "default");
} else {
free(cm);
free(cs);
free(cd);
}
@ -1014,8 +1040,8 @@ midicat_main(int argc, char **argv)
while (!SLIST_EMPTY(&cd->mids)) {
cm = SLIST_FIRST(&cd->mids);
SLIST_REMOVE_HEAD(&cd->mids, entry);
if (!dev_thruadd(d, cm->path, 1, 1))
errx(1, "%s: can't open device", cm->path);
if (!devctl_add(d, cm->path, cm->hold, MODE_MIDIMASK))
errx(1, "%s: can't open port", cm->path);
free(cm);
}

View File

@ -105,6 +105,7 @@ void dev_close(struct dev *);
void dev_start(struct dev *);
void dev_stop(struct dev *);
void dev_clear(struct dev *);
int devctl_open(struct dev *, struct devctl *);
struct dev *dev_list = NULL;
@ -123,6 +124,7 @@ dev_new_sio(char *path,
perror("malloc");
exit(1);
}
d->ctl_list = NULL;
d->path = path;
d->reqmode = mode;
if (mode & MODE_PLAY)
@ -158,6 +160,7 @@ dev_new_loop(struct aparams *dipar, struct aparams *dopar, unsigned bufsz)
perror("malloc");
exit(1);
}
d->ctl_list = NULL;
cmin = (dipar->cmin < dopar->cmin) ? dipar->cmin : dopar->cmin;
cmax = (dipar->cmax > dopar->cmax) ? dipar->cmax : dopar->cmax;
rate = (dipar->rate > dopar->rate) ? dipar->rate : dopar->rate;
@ -189,6 +192,7 @@ dev_new_thru(void)
perror("malloc");
exit(1);
}
d->ctl_list = NULL;
d->reqmode = MODE_MIDIMASK;
d->pstate = DEV_CLOSED;
d->hold = 0;
@ -198,6 +202,62 @@ dev_new_thru(void)
return d;
}
/*
* Add a MIDI port to the device
*/
int
devctl_add(struct dev *d, char *name, int hold, unsigned mode)
{
struct devctl *c;
if (hold) {
if (!dev_ref(d))
return 0;
}
c = malloc(sizeof(struct devctl));
if (c == NULL) {
perror("malloc");
exit(1);
}
c->path = name;
c->hold = hold;
c->mode = mode;
c->next = d->ctl_list;
d->ctl_list = c;
if (d->pstate != DEV_CLOSED) {
if (!devctl_open(d, c))
return 0;
}
return 1;
}
/*
* Open a MIDI device and connect it to the thru box
*/
int
devctl_open(struct dev *d, struct devctl *c)
{
struct file *f;
struct abuf *rbuf = NULL, *wbuf = NULL;
struct aproc *rproc, *wproc;
f = (struct file *)miofile_new(&miofile_ops, c->path, c->mode);
if (f == NULL)
return 0;
if (c->mode & MODE_MIDIIN) {
rproc = rfile_new(f);
rbuf = abuf_new(MIDI_BUFSZ, &aparams_none);
aproc_setout(rproc, rbuf);
}
if (c->mode & MODE_MIDIOUT) {
wproc = wfile_new(f);
wbuf = abuf_new(MIDI_BUFSZ, &aparams_none);
aproc_setin(wproc, wbuf);
}
dev_midiattach(d, rbuf, wbuf);
return 1;
}
/*
* Open the device with the dev_reqxxx capabilities. Setup a mixer, demuxer,
* monitor, midi control, and any necessary conversions.
@ -206,6 +266,7 @@ int
dev_open(struct dev *d)
{
struct file *f;
struct devctl *c;
struct aparams par;
struct aproc *conv;
struct abuf *buf;
@ -399,6 +460,18 @@ dev_open(struct dev *d)
}
#endif
d->pstate = DEV_INIT;
for (c = d->ctl_list; c != NULL; c = c->next) {
if (!devctl_open(d, c)) {
#ifdef DEBUG
if (debug_level >= 1) {
dbg_puts(c->path);
dbg_puts(": couldn't open MIDI port\n");
}
#endif
dev_close(d);
return 0;
}
}
return 1;
}
@ -575,35 +648,6 @@ dev_del(struct dev *d)
free(d);
}
/*
* Open a MIDI device and connect it to the thru box
*/
int
dev_thruadd(struct dev *d, char *name, int in, int out)
{
struct file *f;
struct abuf *rbuf = NULL, *wbuf = NULL;
struct aproc *rproc, *wproc;
if (!dev_ref(d))
return 0;
f = (struct file *)miofile_new(&miofile_ops, name, in, out);
if (f == NULL)
return 0;
if (in) {
rproc = rfile_new(f);
rbuf = abuf_new(MIDI_BUFSZ, &aparams_none);
aproc_setout(rproc, rbuf);
}
if (out) {
wproc = wfile_new(f);
wbuf = abuf_new(MIDI_BUFSZ, &aparams_none);
aproc_setin(wproc, wbuf);
}
dev_midiattach(d, rbuf, wbuf);
return 1;
}
/*
* Attach a bi-directional MIDI stream to the MIDI device
*/

View File

@ -52,6 +52,12 @@ struct dev {
struct aproc *mix, *sub, *submon;
struct aproc *rec, *play, *mon;
struct aproc *midi;
struct devctl {
struct devctl *next;
char *path;
unsigned mode;
int hold;
} *ctl_list;
};
extern struct dev *dev_list;
@ -67,7 +73,7 @@ struct dev *dev_new_loop(struct aparams *, struct aparams *, unsigned);
struct dev *dev_new_sio(char *, unsigned,
struct aparams *, struct aparams *,
unsigned, unsigned, unsigned, unsigned);
int dev_thruadd(struct dev *, char *, int, int);
int devctl_add(struct dev *, char *, int, unsigned);
void dev_midiattach(struct dev *, struct abuf *, struct abuf *);
unsigned dev_roundof(struct dev *, unsigned);
int dev_getpos(struct dev *);

View File

@ -23,6 +23,7 @@
.Sh SYNOPSIS
.Nm midicat
.Op Fl dl
.Op Fl a Ar flag
.Op Fl i Ar file
.Op Fl L Ar addr
.Op Fl o Ar file
@ -47,6 +48,19 @@ MIDI hardware or to another application in a uniform way.
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl a Ar flag
Control whether
.Nm
opens the MIDI port only when needed or keeps it open all the time.
If the flag is
.Va on
then it is kept open all the time, ensuring no other program can steal it.
If the flag is
.Va off ,
then it's automatically closed, allowing other programs to have direct
access to it, or the corresponding MIDI hardware to be disconnected.
The default is
.Va on .
.It Fl d
Increase log verbosity.
.Nm

View File

@ -1,4 +1,4 @@
/* $OpenBSD: miofile.c,v 1.5 2010/06/04 06:15:28 ratchov Exp $ */
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@ -62,18 +62,13 @@ struct fileops miofile_ops = {
* open the device
*/
struct miofile *
miofile_new(struct fileops *ops, char *path, int input, int output)
miofile_new(struct fileops *ops, char *path, unsigned mode)
{
char *siopath;
struct mio_hdl *hdl;
struct miofile *f;
int mode = 0;
siopath = (strcmp(path, "default") == 0) ? NULL : path;
if (input)
mode |= MIO_IN;
if (output)
mode |= MIO_OUT;
hdl = mio_open(siopath, mode, 1);
if (hdl == NULL)
return NULL;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: miofile.h,v 1.1 2009/07/25 08:44:27 ratchov Exp $ */
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@ -21,7 +21,7 @@ struct file;
struct fileops;
struct miofile;
struct miofile *miofile_new(struct fileops *, char *, int, int);
struct miofile *miofile_new(struct fileops *, char *, unsigned);
extern struct fileops miofile_ops;