mirror of https://github.com/ericonr/sndio.git
run play and rec cycles together: simpler and more robust
This commit is contained in:
parent
d02745522d
commit
32d0426047
349
sndiod/dev.c
349
sndiod/dev.c
|
@ -56,11 +56,10 @@ int play_filt_dec(struct slot *, void *, void *, int);
|
||||||
void dev_mix_badd(struct dev *, struct slot *);
|
void dev_mix_badd(struct dev *, struct slot *);
|
||||||
void dev_empty_cycle(struct dev *);
|
void dev_empty_cycle(struct dev *);
|
||||||
void dev_mix_adjvol(struct dev *);
|
void dev_mix_adjvol(struct dev *);
|
||||||
void dev_mix_cycle(struct dev *);
|
|
||||||
int rec_filt_resamp(struct slot *, void *, void *, int);
|
int rec_filt_resamp(struct slot *, void *, void *, int);
|
||||||
int rec_filt_enc(struct slot *, void *, void *, int);
|
int rec_filt_enc(struct slot *, void *, void *, int);
|
||||||
void dev_sub_bcopy(struct dev *, struct slot *);
|
void dev_sub_bcopy(struct dev *, struct slot *);
|
||||||
void dev_sub_cycle(struct dev *);
|
void dev_full_cycle(struct dev *);
|
||||||
|
|
||||||
void dev_onmove(struct dev *, int);
|
void dev_onmove(struct dev *, int);
|
||||||
void dev_master(struct dev *, unsigned int);
|
void dev_master(struct dev *, unsigned int);
|
||||||
|
@ -96,8 +95,7 @@ void slot_detach(struct slot *);
|
||||||
void slot_stop(struct slot *);
|
void slot_stop(struct slot *);
|
||||||
void slot_write(struct slot *);
|
void slot_write(struct slot *);
|
||||||
void slot_read(struct slot *);
|
void slot_read(struct slot *);
|
||||||
void slot_mix_drop(struct slot *);
|
int slot_skip(struct slot *);
|
||||||
void slot_sub_sil(struct slot *);
|
|
||||||
|
|
||||||
struct midiops dev_midiops = {
|
struct midiops dev_midiops = {
|
||||||
dev_midi_imsg,
|
dev_midi_imsg,
|
||||||
|
@ -542,44 +540,42 @@ dev_midi_exit(void *arg)
|
||||||
dev_close(d);
|
dev_close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
slot_mix_drop(struct slot *s)
|
slot_skip(struct slot *s)
|
||||||
{
|
|
||||||
while (s->mix.drop > 0 && s->mix.buf.used >= s->round * s->mix.bpf) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (log_level >= 4) {
|
|
||||||
slot_log(s);
|
|
||||||
log_puts(": dropped a play block\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf);
|
|
||||||
s->mix.drop--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
slot_sub_sil(struct slot *s)
|
|
||||||
{
|
{
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int count;
|
int max, count;
|
||||||
|
|
||||||
while (s->sub.silence > 0) {
|
max = s->skip;
|
||||||
data = abuf_wgetblk(&s->sub.buf, &count);
|
while (s->skip > 0) {
|
||||||
if (count < s->round * s->sub.bpf)
|
if (s->mode & MODE_RECMASK) {
|
||||||
break;
|
data = abuf_wgetblk(&s->sub.buf, &count);
|
||||||
|
if (count < s->round * s->sub.bpf)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (s->mode & MODE_PLAY) {
|
||||||
|
if (s->mix.buf.used < s->round * s->mix.bpf)
|
||||||
|
break;
|
||||||
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (log_level >= 4) {
|
if (log_level >= 4) {
|
||||||
slot_log(s);
|
slot_log(s);
|
||||||
log_puts(": inserted a rec block of silence\n");
|
log_puts(": skipped a cycle\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (s->sub.encbuf)
|
if (s->mode & MODE_RECMASK) {
|
||||||
enc_sil_do(&s->sub.enc, data, s->round);
|
if (s->sub.encbuf)
|
||||||
else
|
enc_sil_do(&s->sub.enc, data, s->round);
|
||||||
memset(data, 0, s->round * s->sub.bpf);
|
else
|
||||||
abuf_wcommit(&s->sub.buf, s->round * s->sub.bpf);
|
memset(data, 0, s->round * s->sub.bpf);
|
||||||
s->sub.silence--;
|
abuf_wcommit(&s->sub.buf, s->round * s->sub.bpf);
|
||||||
|
}
|
||||||
|
if (s->mode & MODE_PLAY) {
|
||||||
|
abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf);
|
||||||
|
}
|
||||||
|
s->skip--;
|
||||||
}
|
}
|
||||||
|
return max - s->skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -717,99 +713,6 @@ dev_mix_adjvol(struct dev *d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
dev_mix_cycle(struct dev *d)
|
|
||||||
{
|
|
||||||
struct slot *s, **ps;
|
|
||||||
unsigned char *base;
|
|
||||||
int nsamp;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (log_level >= 4) {
|
|
||||||
dev_log(d);
|
|
||||||
log_puts(": dev_mix_cycle, poffs = ");
|
|
||||||
log_puti(d->poffs);
|
|
||||||
log_puts("\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
base = (unsigned char *)DEV_PBUF(d);
|
|
||||||
nsamp = d->round * d->pchan;
|
|
||||||
memset(base, 0, nsamp * sizeof(adata_t));
|
|
||||||
ps = &d->slot_list;
|
|
||||||
while ((s = *ps) != NULL) {
|
|
||||||
if (!(s->mode & MODE_PLAY)) {
|
|
||||||
ps = &s->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (log_level >= 4) {
|
|
||||||
slot_log(s);
|
|
||||||
log_puts(": mixing, drop = ");
|
|
||||||
log_puti(s->mix.drop);
|
|
||||||
log_puts(" cycles\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
slot_mix_drop(s);
|
|
||||||
if (s->mix.drop < 0) {
|
|
||||||
s->mix.drop++;
|
|
||||||
ps = &s->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (s->mix.buf.used < s->round * s->mix.bpf &&
|
|
||||||
s->pstate == SLOT_STOP) {
|
|
||||||
/*
|
|
||||||
* partial blocks are zero-filled by socket
|
|
||||||
* layer
|
|
||||||
*/
|
|
||||||
s->pstate = SLOT_INIT;
|
|
||||||
abuf_done(&s->mix.buf);
|
|
||||||
if (s->mix.decbuf)
|
|
||||||
xfree(s->mix.decbuf);
|
|
||||||
if (s->mix.resampbuf)
|
|
||||||
xfree(s->mix.resampbuf);
|
|
||||||
s->ops->eof(s->arg);
|
|
||||||
*ps = s->next;
|
|
||||||
dev_mix_adjvol(d);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (s->mix.buf.used < s->round * s->mix.bpf &&
|
|
||||||
!(s->pstate == SLOT_STOP)) {
|
|
||||||
if (s->xrun == XRUN_IGNORE) {
|
|
||||||
if (s->mode & MODE_RECMASK)
|
|
||||||
s->sub.silence--;
|
|
||||||
s->delta -= s->round;
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (log_level >= 3) {
|
|
||||||
slot_log(s);
|
|
||||||
log_puts(": underrun, pause cycle\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
ps = &s->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (s->xrun == XRUN_SYNC) {
|
|
||||||
s->mix.drop++;
|
|
||||||
ps = &s->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (s->xrun == XRUN_ERROR) {
|
|
||||||
s->ops->exit(s->arg);
|
|
||||||
*ps = s->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dev_mix_badd(d, s);
|
|
||||||
if (s->pstate != SLOT_STOP)
|
|
||||||
s->ops->fill(s->arg);
|
|
||||||
}
|
|
||||||
ps = &s->next;
|
|
||||||
}
|
|
||||||
if (d->encbuf) {
|
|
||||||
enc_do(&d->enc, (unsigned char *)DEV_PBUF(d),
|
|
||||||
d->encbuf, d->round);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
rec_filt_resamp(struct slot *s, void *in, void *res_out, int todo)
|
rec_filt_resamp(struct slot *s, void *in, void *res_out, int todo)
|
||||||
{
|
{
|
||||||
|
@ -873,60 +776,134 @@ dev_sub_bcopy(struct dev *d, struct slot *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dev_sub_cycle(struct dev *d)
|
dev_full_cycle(struct dev *d)
|
||||||
{
|
{
|
||||||
struct slot *s, **ps;
|
struct slot *s, **ps;
|
||||||
|
unsigned char *base;
|
||||||
|
int nsamp;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (log_level >= 4) {
|
if (log_level >= 4) {
|
||||||
dev_log(d);
|
dev_log(d);
|
||||||
log_puts(": dev_sub_cycle\n");
|
log_puts(": dev_full_cycle");
|
||||||
|
if (d->mode & MODE_PLAY) {
|
||||||
|
log_puts(", poffs = ");
|
||||||
|
log_puti(d->poffs);
|
||||||
|
}
|
||||||
|
log_puts("\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (d->mode & MODE_PLAY) {
|
||||||
|
base = (unsigned char *)DEV_PBUF(d);
|
||||||
|
nsamp = d->round * d->pchan;
|
||||||
|
memset(base, 0, nsamp * sizeof(adata_t));
|
||||||
|
}
|
||||||
if ((d->mode & MODE_REC) && d->decbuf)
|
if ((d->mode & MODE_REC) && d->decbuf)
|
||||||
dec_do(&d->dec, d->decbuf, (unsigned char *)d->rbuf, d->round);
|
dec_do(&d->dec, d->decbuf, (unsigned char *)d->rbuf, d->round);
|
||||||
ps = &d->slot_list;
|
ps = &d->slot_list;
|
||||||
while ((s = *ps) != NULL) {
|
while ((s = *ps) != NULL) {
|
||||||
if (!(s->mode & MODE_RECMASK) || s->pstate == SLOT_STOP) {
|
|
||||||
ps = &s->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
slot_sub_sil(s);
|
|
||||||
if (s->sub.silence < 0) {
|
|
||||||
s->sub.silence++;
|
|
||||||
ps = &s->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (s->sub.buf.len - s->sub.buf.used < s->round * s->sub.bpf) {
|
|
||||||
if (s->xrun == XRUN_IGNORE) {
|
|
||||||
if (s->mode & MODE_PLAY)
|
|
||||||
s->mix.drop--;
|
|
||||||
s->delta -= s->round;
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (log_level >= 3) {
|
if (log_level >= 4) {
|
||||||
slot_log(s);
|
slot_log(s);
|
||||||
log_puts(": overrun, pause cycle\n");
|
log_puts(": running");
|
||||||
}
|
log_puts(", skip = ");
|
||||||
|
log_puti(s->skip);
|
||||||
|
log_puts("\n");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
slot_skip(s);
|
||||||
|
if (s->skip < 0) {
|
||||||
|
s->skip++;
|
||||||
|
ps = &s->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check if stopped stream finished draining
|
||||||
|
*/
|
||||||
|
if (s->pstate == SLOT_STOP) {
|
||||||
|
if (s->mode & MODE_PLAY) {
|
||||||
|
if (s->mix.buf.used < s->round * s->mix.bpf) {
|
||||||
|
/*
|
||||||
|
* partial blocks are
|
||||||
|
* zero-filled by socket layer
|
||||||
|
*/
|
||||||
|
s->pstate = SLOT_INIT;
|
||||||
|
abuf_done(&s->mix.buf);
|
||||||
|
if (s->mix.decbuf)
|
||||||
|
xfree(s->mix.decbuf);
|
||||||
|
if (s->mix.resampbuf)
|
||||||
|
xfree(s->mix.resampbuf);
|
||||||
|
s->ops->eof(s->arg);
|
||||||
|
*ps = s->next;
|
||||||
|
dev_mix_adjvol(d);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
ps = &s->next;
|
ps = &s->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (s->xrun == XRUN_SYNC) {
|
}
|
||||||
s->sub.silence++;
|
|
||||||
ps = &s->next;
|
/*
|
||||||
continue;
|
* check for xruns
|
||||||
|
*/
|
||||||
|
if (((s->mode & MODE_PLAY) &&
|
||||||
|
s->mix.buf.used < s->round * s->mix.bpf &&
|
||||||
|
!(s->pstate == SLOT_STOP)) ||
|
||||||
|
((s->mode & MODE_RECMASK) &&
|
||||||
|
s->sub.buf.len - s->sub.buf.used <
|
||||||
|
s->round * s->sub.bpf)) {
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (log_level >= 3) {
|
||||||
|
slot_log(s);
|
||||||
|
log_puts(": xrun, pause cycle\n");
|
||||||
}
|
}
|
||||||
if (s->xrun == XRUN_ERROR) {
|
#endif
|
||||||
|
if (s->xrun == XRUN_IGNORE) {
|
||||||
|
s->delta -= s->round;
|
||||||
|
ps = &s->next;
|
||||||
|
} else if (s->xrun == XRUN_SYNC) {
|
||||||
|
s->skip++;
|
||||||
|
ps = &s->next;
|
||||||
|
} else if (s->xrun == XRUN_ERROR) {
|
||||||
s->ops->exit(s->arg);
|
s->ops->exit(s->arg);
|
||||||
*ps = s->next;
|
*ps = s->next;
|
||||||
continue;
|
} else {
|
||||||
|
#ifdef DEBUG
|
||||||
|
slot_log(s);
|
||||||
|
log_puts(": bad xrun mode\n");
|
||||||
|
panic();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (s->mode & MODE_PLAY) {
|
||||||
|
dev_mix_badd(d, s);
|
||||||
|
if (s->pstate != SLOT_STOP)
|
||||||
|
s->ops->fill(s->arg);
|
||||||
|
}
|
||||||
|
if (s->mode & MODE_RECMASK) {
|
||||||
|
if (s->sub.prime == 0) {
|
||||||
|
dev_sub_bcopy(d, s);
|
||||||
|
s->ops->flush(s->arg);
|
||||||
|
} else {
|
||||||
|
#ifdef DEBUG
|
||||||
|
slot_log(s);
|
||||||
|
log_puts(": prime = ");
|
||||||
|
log_puti(s->sub.prime);
|
||||||
|
log_puts("\n");
|
||||||
|
#endif
|
||||||
|
s->sub.prime--;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
dev_sub_bcopy(d, s);
|
|
||||||
s->ops->flush(s->arg);
|
|
||||||
}
|
}
|
||||||
ps = &s->next;
|
ps = &s->next;
|
||||||
}
|
}
|
||||||
|
if ((d->mode & MODE_PLAY) && d->encbuf) {
|
||||||
|
enc_do(&d->enc, (unsigned char *)DEV_PBUF(d),
|
||||||
|
d->encbuf, d->round);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -995,10 +972,7 @@ dev_cycle(struct dev *d)
|
||||||
d->prime -= d->round;
|
d->prime -= d->round;
|
||||||
dev_empty_cycle(d);
|
dev_empty_cycle(d);
|
||||||
} else {
|
} else {
|
||||||
if (d->mode & MODE_RECMASK)
|
dev_full_cycle(d);
|
||||||
dev_sub_cycle(d);
|
|
||||||
if (d->mode & MODE_PLAY)
|
|
||||||
dev_mix_cycle(d);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1715,6 +1689,7 @@ slot_attach(struct slot *s)
|
||||||
#endif
|
#endif
|
||||||
s->next = d->slot_list;
|
s->next = d->slot_list;
|
||||||
d->slot_list = s;
|
d->slot_list = s;
|
||||||
|
s->skip = 0;
|
||||||
if (s->mode & MODE_PLAY) {
|
if (s->mode & MODE_PLAY) {
|
||||||
slot_nch = s->mix.slot_cmax - s->mix.slot_cmin + 1;
|
slot_nch = s->mix.slot_cmax - s->mix.slot_cmin + 1;
|
||||||
dev_nch = s->mix.dev_cmax - s->mix.dev_cmin + 1;
|
dev_nch = s->mix.dev_cmax - s->mix.dev_cmin + 1;
|
||||||
|
@ -1744,7 +1719,6 @@ slot_attach(struct slot *s)
|
||||||
s->mix.resampbuf =
|
s->mix.resampbuf =
|
||||||
xmalloc(d->round * slot_nch * sizeof(adata_t));
|
xmalloc(d->round * slot_nch * sizeof(adata_t));
|
||||||
}
|
}
|
||||||
s->mix.drop = 0;
|
|
||||||
s->mix.vol = MIDI_TO_ADATA(s->vol);
|
s->mix.vol = MIDI_TO_ADATA(s->vol);
|
||||||
dev_mix_adjvol(d);
|
dev_mix_adjvol(d);
|
||||||
}
|
}
|
||||||
|
@ -1781,7 +1755,7 @@ slot_attach(struct slot *s)
|
||||||
/*
|
/*
|
||||||
* N-th recorded block is the N-th played block
|
* N-th recorded block is the N-th played block
|
||||||
*/
|
*/
|
||||||
s->sub.silence = startpos / (int)s->round;
|
s->sub.prime = -startpos / (int)s->round;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1960,6 +1934,27 @@ slot_stop(struct slot *s)
|
||||||
s->tstate = MMC_STOP;
|
s->tstate = MMC_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
slot_skip_update(struct slot *s)
|
||||||
|
{
|
||||||
|
int skip;
|
||||||
|
|
||||||
|
skip = slot_skip(s);
|
||||||
|
while (skip > 0) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (log_level >= 4) {
|
||||||
|
slot_log(s);
|
||||||
|
log_puts(": catching skipped block\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (s->mode & MODE_RECMASK)
|
||||||
|
s->ops->flush(s->arg);
|
||||||
|
if (s->mode & MODE_PLAY)
|
||||||
|
s->ops->fill(s->arg);
|
||||||
|
skip--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* notify the slot that we just wrote in the play buffer, must be called
|
* notify the slot that we just wrote in the play buffer, must be called
|
||||||
* after each write
|
* after each write
|
||||||
|
@ -1967,8 +1962,6 @@ slot_stop(struct slot *s)
|
||||||
void
|
void
|
||||||
slot_write(struct slot *s)
|
slot_write(struct slot *s)
|
||||||
{
|
{
|
||||||
int drop;
|
|
||||||
|
|
||||||
if (s->pstate == SLOT_START && s->mix.buf.used == s->mix.buf.len) {
|
if (s->pstate == SLOT_START && s->mix.buf.used == s->mix.buf.len) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (log_level >= 4) {
|
if (log_level >= 4) {
|
||||||
|
@ -1979,18 +1972,7 @@ slot_write(struct slot *s)
|
||||||
s->pstate = SLOT_READY;
|
s->pstate = SLOT_READY;
|
||||||
slot_ready(s);
|
slot_ready(s);
|
||||||
}
|
}
|
||||||
drop = s->mix.drop;
|
slot_skip_update(s);
|
||||||
slot_mix_drop(s);
|
|
||||||
while (drop > s->mix.drop) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (log_level >= 4) {
|
|
||||||
slot_log(s);
|
|
||||||
log_puts(": catching play block\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
s->ops->fill(s->arg);
|
|
||||||
drop--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1999,18 +1981,5 @@ slot_write(struct slot *s)
|
||||||
void
|
void
|
||||||
slot_read(struct slot *s)
|
slot_read(struct slot *s)
|
||||||
{
|
{
|
||||||
int sil;
|
slot_skip_update(s);
|
||||||
|
|
||||||
sil = s->sub.silence;
|
|
||||||
slot_sub_sil(s);
|
|
||||||
while (sil > s->sub.silence) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (log_level >= 4) {
|
|
||||||
slot_log(s);
|
|
||||||
log_puts(": catching rec block\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
s->ops->flush(s->arg);
|
|
||||||
sil--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,6 @@ struct slot {
|
||||||
int weight; /* dynamic range */
|
int weight; /* dynamic range */
|
||||||
int maxweight; /* max dynamic range allowed */
|
int maxweight; /* max dynamic range allowed */
|
||||||
unsigned int vol; /* volume within the vol */
|
unsigned int vol; /* volume within the vol */
|
||||||
int drop; /* to drop on next read */
|
|
||||||
struct abuf buf; /* socket side buffer */
|
struct abuf buf; /* socket side buffer */
|
||||||
int bpf; /* byte per frame */
|
int bpf; /* byte per frame */
|
||||||
int slot_cmin, slot_cmax; /* slot source chans */
|
int slot_cmin, slot_cmax; /* slot source chans */
|
||||||
|
@ -61,8 +60,8 @@ struct slot {
|
||||||
void *resampbuf, *decbuf; /* tmp buffers */
|
void *resampbuf, *decbuf; /* tmp buffers */
|
||||||
} mix;
|
} mix;
|
||||||
struct {
|
struct {
|
||||||
int silence; /* to add on next write */
|
|
||||||
struct abuf buf; /* socket side buffer */
|
struct abuf buf; /* socket side buffer */
|
||||||
|
int prime; /* initial cycles to skip */
|
||||||
int bpf; /* byte per frame */
|
int bpf; /* byte per frame */
|
||||||
int slot_cmin, slot_cmax; /* slot destination chans */
|
int slot_cmin, slot_cmax; /* slot destination chans */
|
||||||
int dev_cmin, dev_cmax; /* device source chans */
|
int dev_cmin, dev_cmax; /* device source chans */
|
||||||
|
@ -74,6 +73,7 @@ struct slot {
|
||||||
void *resampbuf, *encbuf; /* tmp buffers */
|
void *resampbuf, *encbuf; /* tmp buffers */
|
||||||
} sub;
|
} sub;
|
||||||
int xrun; /* underrun policy */
|
int xrun; /* underrun policy */
|
||||||
|
int skip; /* cycles to skip (for xrun) */
|
||||||
int dup; /* mono-to-stereo and alike */
|
int dup; /* mono-to-stereo and alike */
|
||||||
#define SLOT_BUFSZ(s) \
|
#define SLOT_BUFSZ(s) \
|
||||||
((s)->appbufsz + (s)->dev->bufsz / (s)->dev->round * (s)->round)
|
((s)->appbufsz + (s)->dev->bufsz / (s)->dev->round * (s)->round)
|
||||||
|
|
Loading…
Reference in New Issue