version 1.50, 2010/06/05 16:00:52 |
version 1.51, 2010/10/21 18:57:42 |
|
|
void |
void |
sock_dbg(struct sock *f) |
sock_dbg(struct sock *f) |
{ |
{ |
static char *pstates[] = { "hel", "ini", "sta", "rdy", "run", "mid" }; |
static char *pstates[] = { |
|
"hel", "ini", "sta", "rdy", "run", "stp", "mid" |
|
}; |
static char *rstates[] = { "rdat", "rmsg", "rret" }; |
static char *rstates[] = { "rdat", "rmsg", "rret" }; |
static char *wstates[] = { "widl", "wmsg", "wdat" }; |
static char *wstates[] = { "widl", "wmsg", "wdat" }; |
struct aproc *midi; |
struct aproc *midi; |
|
|
{ |
{ |
struct sock *f = (struct sock *)p->u.io.file; |
struct sock *f = (struct sock *)p->u.io.file; |
|
|
if (f->mode & AMSG_RECMASK) |
if (f->mode & MODE_RECMASK) |
return; |
return; |
|
|
f->delta += delta; |
f->delta += delta; |
|
|
{ |
{ |
struct sock *f = (struct sock *)p->u.io.file; |
struct sock *f = (struct sock *)p->u.io.file; |
|
|
if (!(f->mode & AMSG_RECMASK)) |
if (!(f->mode & MODE_RECMASK)) |
return; |
return; |
|
|
f->delta += delta; |
f->delta += delta; |
|
|
f->mode = 0; |
f->mode = 0; |
f->opt = NULL; |
f->opt = NULL; |
f->dev = NULL; |
f->dev = NULL; |
f->xrun = AMSG_IGNORE; |
f->xrun = XRUN_IGNORE; |
f->delta = 0; |
f->delta = 0; |
f->tickpending = 0; |
f->tickpending = 0; |
f->startpos = 0; |
f->startpos = 0; |
|
|
|
|
bufsz = f->bufsz + f->dev->bufsz / f->dev->round * f->round; |
bufsz = f->bufsz + f->dev->bufsz / f->dev->round * f->round; |
f->pstate = SOCK_START; |
f->pstate = SOCK_START; |
if (f->mode & AMSG_PLAY) { |
if (f->mode & MODE_PLAY) { |
rbuf = abuf_new(bufsz, &f->rpar); |
rbuf = abuf_new(bufsz, &f->rpar); |
aproc_setout(f->pipe.file.rproc, rbuf); |
aproc_setout(f->pipe.file.rproc, rbuf); |
if (!ABUF_WOK(rbuf) || (f->pipe.file.state & FILE_EOF)) |
if (!ABUF_WOK(rbuf) || (f->pipe.file.state & FILE_EOF)) |
f->pstate = SOCK_READY; |
f->pstate = SOCK_READY; |
f->rmax = bufsz * aparams_bpf(&f->rpar); |
f->rmax = bufsz * aparams_bpf(&f->rpar); |
} |
} |
if (f->mode & AMSG_RECMASK) { |
if (f->mode & MODE_RECMASK) { |
wbuf = abuf_new(bufsz, &f->wpar); |
wbuf = abuf_new(bufsz, &f->wpar); |
aproc_setin(f->pipe.file.wproc, wbuf); |
aproc_setin(f->pipe.file.wproc, wbuf); |
f->walign = f->round; |
f->walign = f->round; |
|
|
dbg_puts("\n"); |
dbg_puts("\n"); |
} |
} |
#endif |
#endif |
if (f->mode & AMSG_PLAY) { |
if (f->mode & MODE_PLAY) { |
f->pstate = SOCK_START; |
f->pstate = SOCK_START; |
} else { |
} else { |
f->pstate = SOCK_READY; |
f->pstate = SOCK_READY; |
|
|
} |
} |
#endif |
#endif |
(void)sock_attach(f, 0); |
(void)sock_attach(f, 0); |
} |
}/* |
|
|
/* |
|
* Callback invoked by MMC stop |
* Callback invoked by MMC stop |
*/ |
*/ |
void |
void |
|
|
} |
} |
|
|
/* |
/* |
* Attach play and/or record buffers to dev->mix and/or dev->sub. |
* Attach play and/or record buffers to the device |
*/ |
*/ |
void |
void |
sock_attach(struct sock *f, int force) |
sock_attach(struct sock *f, int force) |
|
|
wbuf, &f->wpar, |
wbuf, &f->wpar, |
f->opt->join ? f->opt->wpar.cmax - f->opt->wpar.cmin + 1 : 0, |
f->opt->join ? f->opt->wpar.cmax - f->opt->wpar.cmin + 1 : 0, |
f->xrun, f->opt->maxweight); |
f->xrun, f->opt->maxweight); |
if (f->mode & AMSG_PLAY) |
if (f->mode & MODE_PLAY) |
dev_setvol(f->dev, rbuf, MIDI_TO_ADATA(f->vol)); |
dev_setvol(f->dev, rbuf, MIDI_TO_ADATA(f->vol)); |
|
|
/* |
/* |
|
|
f->rpar.le = f->wpar.le = p->le ? 1 : 0; |
f->rpar.le = f->wpar.le = p->le ? 1 : 0; |
if (AMSG_ISSET(p->msb)) |
if (AMSG_ISSET(p->msb)) |
f->rpar.msb = f->wpar.msb = p->msb ? 1 : 0; |
f->rpar.msb = f->wpar.msb = p->msb ? 1 : 0; |
if (AMSG_ISSET(p->rchan) && (f->mode & AMSG_RECMASK)) { |
if (AMSG_ISSET(p->rchan) && (f->mode & MODE_RECMASK)) { |
if (p->rchan < 1) |
if (p->rchan < 1) |
p->rchan = 1; |
p->rchan = 1; |
if (p->rchan > NCHAN_MAX) |
if (p->rchan > NCHAN_MAX) |
|
|
} |
} |
#endif |
#endif |
} |
} |
if (AMSG_ISSET(p->pchan) && (f->mode & AMSG_PLAY)) { |
if (AMSG_ISSET(p->pchan) && (f->mode & MODE_PLAY)) { |
if (p->pchan < 1) |
if (p->pchan < 1) |
p->pchan = 1; |
p->pchan = 1; |
if (p->pchan > NCHAN_MAX) |
if (p->pchan > NCHAN_MAX) |
|
|
#endif |
#endif |
} |
} |
if (AMSG_ISSET(p->xrun)) { |
if (AMSG_ISSET(p->xrun)) { |
if (p->xrun != AMSG_IGNORE && |
if (p->xrun != XRUN_IGNORE && |
p->xrun != AMSG_SYNC && |
p->xrun != XRUN_SYNC && |
p->xrun != AMSG_ERROR) { |
p->xrun != XRUN_ERROR) { |
#ifdef DEBUG |
#ifdef DEBUG |
if (debug_level >= 1) { |
if (debug_level >= 1) { |
sock_dbg(f); |
sock_dbg(f); |
|
|
return 0; |
return 0; |
} |
} |
f->xrun = p->xrun; |
f->xrun = p->xrun; |
if (f->opt->mmc && f->xrun == AMSG_IGNORE) |
if (f->opt->mmc && f->xrun == XRUN_IGNORE) |
f->xrun = AMSG_SYNC; |
f->xrun = XRUN_SYNC; |
#ifdef DEBUG |
#ifdef DEBUG |
if (debug_level >= 3) { |
if (debug_level >= 3) { |
sock_dbg(f); |
sock_dbg(f); |
|
|
#endif |
#endif |
} |
} |
if (AMSG_ISSET(p->appbufsz)) { |
if (AMSG_ISSET(p->appbufsz)) { |
rate = (f->mode & AMSG_PLAY) ? f->rpar.rate : f->wpar.rate; |
rate = (f->mode & MODE_PLAY) ? f->rpar.rate : f->wpar.rate; |
min = 1; |
min = 1; |
max = 1 + rate / f->dev->round; |
max = 1 + rate / f->dev->round; |
min *= f->round; |
min *= f->round; |
|
|
dbg_puts(f->pipe.file.name); |
dbg_puts(f->pipe.file.name); |
dbg_puts(": buffer size = "); |
dbg_puts(": buffer size = "); |
dbg_putu(f->bufsz); |
dbg_putu(f->bufsz); |
if (f->mode & AMSG_PLAY) { |
if (f->mode & MODE_PLAY) { |
dbg_puts(", play = "); |
dbg_puts(", play = "); |
aparams_dbg(&f->rpar); |
aparams_dbg(&f->rpar); |
} |
} |
if (f->mode & AMSG_RECMASK) { |
if (f->mode & MODE_RECMASK) { |
dbg_puts(", rec:"); |
dbg_puts(", rec:"); |
aparams_dbg(&f->wpar); |
aparams_dbg(&f->wpar); |
} |
} |
|
|
* allocate buffers, so client can start filling write-end. |
* allocate buffers, so client can start filling write-end. |
*/ |
*/ |
void |
void |
sock_midiattach(struct sock *f, unsigned mode) |
sock_midiattach(struct sock *f) |
{ |
{ |
struct abuf *rbuf = NULL, *wbuf = NULL; |
struct abuf *rbuf = NULL, *wbuf = NULL; |
|
|
if (mode & AMSG_MIDIOUT) { |
if (f->mode & MODE_MIDIOUT) { |
rbuf = abuf_new(MIDI_BUFSZ, &aparams_none); |
rbuf = abuf_new(MIDI_BUFSZ, &aparams_none); |
aproc_setout(f->pipe.file.rproc, rbuf); |
aproc_setout(f->pipe.file.rproc, rbuf); |
} |
} |
if (mode & AMSG_MIDIIN) { |
if (f->mode & MODE_MIDIIN) { |
wbuf = abuf_new(MIDI_BUFSZ, &aparams_none); |
wbuf = abuf_new(MIDI_BUFSZ, &aparams_none); |
aproc_setin(f->pipe.file.wproc, wbuf); |
aproc_setin(f->pipe.file.wproc, wbuf); |
} |
} |
|
f->pstate = SOCK_MIDI; |
dev_midiattach(f->dev, rbuf, wbuf); |
dev_midiattach(f->dev, rbuf, wbuf); |
} |
} |
|
|
|
|
sock_dbg(f); |
sock_dbg(f); |
dbg_puts(": hello from <"); |
dbg_puts(": hello from <"); |
dbg_puts(p->who); |
dbg_puts(p->who); |
dbg_puts(">, proto = "); |
dbg_puts(">, mode = "); |
dbg_putx(p->proto); |
dbg_putx(p->mode); |
dbg_puts(", ver "); |
dbg_puts(", ver "); |
dbg_putu(p->version); |
dbg_putu(p->version); |
dbg_puts("\n"); |
dbg_puts("\n"); |
|
|
sock_dbg(f); |
sock_dbg(f); |
dbg_puts(": "); |
dbg_puts(": "); |
dbg_putu(p->version); |
dbg_putu(p->version); |
dbg_puts(": bad version\n"); |
dbg_puts(": unsupported protocol version\n"); |
} |
} |
#endif |
#endif |
return 0; |
return 0; |
} |
} |
|
switch (p->mode) { |
|
case MODE_MIDIIN: |
|
case MODE_MIDIOUT: |
|
case MODE_MIDIOUT | MODE_MIDIIN: |
|
case MODE_REC: |
|
case MODE_PLAY: |
|
case MODE_PLAY | MODE_REC: |
|
break; |
|
default: |
|
#ifdef DEBUG |
|
if (debug_level >= 1) { |
|
sock_dbg(f); |
|
dbg_puts(": "); |
|
dbg_putx(p->mode); |
|
dbg_puts(": unsupported mode\n"); |
|
} |
|
#endif |
|
return 0; |
|
} |
f->opt = opt_byname(p->opt); |
f->opt = opt_byname(p->opt); |
if (f->opt == NULL) |
if (f->opt == NULL) |
return 0; |
return 0; |
if (!dev_ref(f->opt->dev)) |
if (!dev_ref(f->opt->dev)) |
return 0; |
return 0; |
|
if ((p->mode & MODE_REC) && (f->opt->mode & MODE_MON)) { |
|
p->mode &= ~MODE_REC; |
|
p->mode |= MODE_MON; |
|
} |
f->dev = f->opt->dev; |
f->dev = f->opt->dev; |
|
f->mode = (p->mode & f->opt->mode) & f->dev->mode; |
if (APROC_OK(f->dev->midi) && (p->proto & (AMSG_MIDIIN | AMSG_MIDIOUT))) { |
|
if (p->proto & ~(AMSG_MIDIIN | AMSG_MIDIOUT)) { |
|
#ifdef DEBUG |
#ifdef DEBUG |
if (debug_level >= 1) { |
if (debug_level >= 3) { |
sock_dbg(f); |
sock_dbg(f); |
dbg_puts(": "); |
dbg_puts(": using mode = "); |
dbg_putx(p->proto); |
dbg_putx(f->mode); |
dbg_puts(": bad hello protocol\n"); |
dbg_puts("\n"); |
} |
|
#endif |
|
return 0; |
|
} |
|
f->mode = p->proto; |
|
f->pstate = SOCK_MIDI; |
|
sock_midiattach(f, p->proto); |
|
return 1; |
|
} |
} |
if (f->opt->mode & MODE_RECMASK) |
#endif |
f->wpar = f->opt->wpar; |
if (f->mode != p->mode) { |
if (f->opt->mode & MODE_PLAY) |
|
f->rpar = f->opt->rpar; |
|
if (f->opt->mmc) |
|
f->xrun = AMSG_SYNC; |
|
f->bufsz = f->dev->bufsz; |
|
f->round = f->dev->round; |
|
if ((p->proto & ~(AMSG_PLAY | AMSG_REC)) != 0 || |
|
(p->proto & (AMSG_PLAY | AMSG_REC)) == 0) { |
|
#ifdef DEBUG |
#ifdef DEBUG |
if (debug_level >= 1) { |
if (debug_level >= 1) { |
sock_dbg(f); |
sock_dbg(f); |
dbg_puts(": "); |
dbg_puts(": requested mode not available\n"); |
dbg_putx(p->proto); |
|
dbg_puts(": unsupported hello protocol\n"); |
|
} |
} |
#endif |
#endif |
return 0; |
return 0; |
} |
} |
f->mode = 0; |
if (f->mode & (MODE_MIDIOUT | MODE_MIDIIN)) { |
if (p->proto & AMSG_PLAY) { |
sock_midiattach(f); |
if (!APROC_OK(f->dev->mix) || !(f->opt->mode & MODE_PLAY)) { |
return 1; |
#ifdef DEBUG |
|
if (debug_level >= 1) { |
|
sock_dbg(f); |
|
dbg_puts(": playback not available\n"); |
|
} |
|
#endif |
|
return 0; |
|
} |
|
f->mode |= AMSG_PLAY; |
|
} |
} |
if (p->proto & AMSG_REC) { |
if (f->mode & MODE_PLAY) |
if (!(APROC_OK(f->dev->sub) && (f->opt->mode & MODE_REC)) && |
f->rpar = f->opt->rpar; |
!(APROC_OK(f->dev->submon) && (f->opt->mode & MODE_MON))) { |
if (f->mode & MODE_RECMASK) |
#ifdef DEBUG |
f->wpar = f->opt->wpar; |
if (debug_level >= 1) { |
f->xrun = (f->opt->mmc) ? XRUN_SYNC : XRUN_IGNORE; |
sock_dbg(f); |
f->bufsz = f->dev->bufsz; |
dbg_puts(": recording not available\n"); |
f->round = f->dev->round; |
} |
f->slot = ctl_slotnew(f->dev->midi, p->who, |
#endif |
&ctl_sockops, f, |
return 0; |
f->opt->mmc); |
} |
if (f->slot < 0) |
f->mode |= (f->opt->mode & MODE_MON) ? AMSG_MON : AMSG_REC; |
return 0; |
} |
|
if (APROC_OK(f->dev->midi)) { |
|
f->slot = ctl_slotnew(f->dev->midi, |
|
p->who, &ctl_sockops, f, |
|
f->opt->mmc); |
|
if (f->slot < 0) { |
|
#ifdef DEBUG |
|
if (debug_level >= 1) { |
|
sock_dbg(f); |
|
dbg_puts(": out of mixer slots\n"); |
|
} |
|
#endif |
|
return 0; |
|
} |
|
} |
|
f->pstate = SOCK_INIT; |
f->pstate = SOCK_INIT; |
return 1; |
return 1; |
} |
} |
|
|
aproc_del(f->pipe.file.rproc); |
aproc_del(f->pipe.file.rproc); |
return 0; |
return 0; |
} |
} |
if (!(f->mode & AMSG_PLAY)) { |
if (!(f->mode & MODE_PLAY)) { |
#ifdef DEBUG |
#ifdef DEBUG |
if (debug_level >= 1) { |
if (debug_level >= 1) { |
sock_dbg(f); |
sock_dbg(f); |
|
|
AMSG_INIT(m); |
AMSG_INIT(m); |
m->cmd = AMSG_GETPAR; |
m->cmd = AMSG_GETPAR; |
m->u.par.legacy_mode = f->mode; |
m->u.par.legacy_mode = f->mode; |
if (f->mode & AMSG_PLAY) { |
if (f->mode & MODE_PLAY) { |
m->u.par.bits = f->rpar.bits; |
m->u.par.bits = f->rpar.bits; |
m->u.par.bps = f->rpar.bps; |
m->u.par.bps = f->rpar.bps; |
m->u.par.sig = f->rpar.sig; |
m->u.par.sig = f->rpar.sig; |
|
|
m->u.par.rate = f->rpar.rate; |
m->u.par.rate = f->rpar.rate; |
m->u.par.pchan = f->rpar.cmax - f->rpar.cmin + 1; |
m->u.par.pchan = f->rpar.cmax - f->rpar.cmin + 1; |
} |
} |
if (f->mode & AMSG_RECMASK) { |
if (f->mode & MODE_RECMASK) { |
m->u.par.bits = f->wpar.bits; |
m->u.par.bits = f->wpar.bits; |
m->u.par.bps = f->wpar.bps; |
m->u.par.bps = f->wpar.bps; |
m->u.par.sig = f->wpar.sig; |
m->u.par.sig = f->wpar.sig; |
|
|
dbg_puts(": RRET done\n"); |
dbg_puts(": RRET done\n"); |
} |
} |
#endif |
#endif |
if (f->pstate == SOCK_MIDI && (f->mode & AMSG_MIDIOUT)) { |
if (f->pstate == SOCK_MIDI && (f->mode & MODE_MIDIOUT)) { |
f->rstate = SOCK_RDATA; |
f->rstate = SOCK_RDATA; |
f->rtodo = 0; |
f->rtodo = 0; |
} else { |
} else { |
|
|
dbg_puts(": sent RRET message\n"); |
dbg_puts(": sent RRET message\n"); |
} |
} |
#endif |
#endif |
if (f->pstate == SOCK_MIDI && (f->mode & AMSG_MIDIOUT)) { |
if (f->pstate == SOCK_MIDI && (f->mode & MODE_MIDIOUT)) { |
f->rstate = SOCK_RDATA; |
f->rstate = SOCK_RDATA; |
f->rtodo = 0; |
f->rtodo = 0; |
} else { |
} else { |