mirror of https://github.com/ericonr/sndio.git
make -a apply on MIDI ports
This commit is contained in:
parent
9429404049
commit
007a5ce2e1
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
102
aucat/dev.c
102
aucat/dev.c
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue