version 1.90, 2021/02/02 11:18:57 |
version 1.91, 2021/03/02 12:15:46 |
|
|
/* |
/* |
* Open the device with the dev_reqxxx capabilities. Setup a mixer, demuxer, |
* Open the device with the dev_reqxxx capabilities. Setup a mixer, demuxer, |
* monitor, midi control, and any necessary conversions. |
* monitor, midi control, and any necessary conversions. |
|
* |
|
* Note that record and play buffers are always allocated, even if the |
|
* underlying device doesn't support both modes. |
*/ |
*/ |
int |
int |
dev_allocbufs(struct dev *d) |
dev_allocbufs(struct dev *d) |
{ |
{ |
if (d->mode & MODE_REC) { |
/* |
/* |
* Create record buffer. |
* Create device <-> demuxer buffer |
*/ |
*/ |
|
d->rbuf = xmalloc(d->round * d->rchan * sizeof(adata_t)); |
|
|
|
/* |
/* Create device <-> demuxer buffer */ |
* Insert a converter, if needed. |
d->rbuf = xmalloc(d->round * d->rchan * sizeof(adata_t)); |
*/ |
|
if (!aparams_native(&d->par)) { |
|
dec_init(&d->dec, &d->par, d->rchan); |
|
d->decbuf = xmalloc(d->round * d->rchan * d->par.bps); |
|
} else |
|
d->decbuf = NULL; |
|
} |
|
if (d->mode & MODE_PLAY) { |
|
/* |
|
* Create device <-> mixer buffer |
|
*/ |
|
d->poffs = 0; |
|
d->psize = d->bufsz + d->round; |
|
d->pbuf = xmalloc(d->psize * d->pchan * sizeof(adata_t)); |
|
d->mode |= MODE_MON; |
|
|
|
/* |
/* Insert a converter, if needed. */ |
* Append a converter, if needed. |
if (!aparams_native(&d->par)) { |
*/ |
dec_init(&d->dec, &d->par, d->rchan); |
if (!aparams_native(&d->par)) { |
d->decbuf = xmalloc(d->round * d->rchan * d->par.bps); |
enc_init(&d->enc, &d->par, d->pchan); |
} else |
d->encbuf = xmalloc(d->round * d->pchan * d->par.bps); |
d->decbuf = NULL; |
} else |
|
d->encbuf = NULL; |
/* |
} |
* Create play buffer |
|
*/ |
|
|
|
/* Create device <-> mixer buffer */ |
|
d->poffs = 0; |
|
d->psize = d->bufsz + d->round; |
|
d->pbuf = xmalloc(d->psize * d->pchan * sizeof(adata_t)); |
|
d->mode |= MODE_MON; |
|
|
|
/* Append a converter, if needed. */ |
|
if (!aparams_native(&d->par)) { |
|
enc_init(&d->enc, &d->par, d->pchan); |
|
d->encbuf = xmalloc(d->round * d->pchan * d->par.bps); |
|
} else |
|
d->encbuf = NULL; |
|
|
|
/* |
|
* Initially fill the record buffer with zeroed samples. This ensures |
|
* that when a client records from a play-only device the client just |
|
* gets silence. |
|
*/ |
|
memset(d->rbuf, 0, d->round * d->rchan * sizeof(adata_t)); |
|
|
if (log_level >= 2) { |
if (log_level >= 2) { |
dev_log(d); |
dev_log(d); |
log_puts(": "); |
log_puts(": "); |
|
|
slot_log(s); |
slot_log(s); |
log_puts(": requested mode not supported\n"); |
log_puts(": requested mode not supported\n"); |
} |
} |
dev_unref(opt->dev); |
|
return NULL; |
|
} |
} |
s->opt = opt; |
s->opt = opt; |
s->ops = ops; |
s->ops = ops; |
|
|
* because dev_xxx() functions are supposed to |
* because dev_xxx() functions are supposed to |
* work (i.e., not to crash) |
* work (i.e., not to crash) |
*/ |
*/ |
#ifdef DEBUG |
|
if ((s->mode & d->mode) != s->mode) { |
|
slot_log(s); |
|
log_puts(": mode beyond device mode, not attaching\n"); |
|
panic(); |
|
} |
|
#endif |
|
s->next = d->slot_list; |
s->next = d->slot_list; |
d->slot_list = s; |
d->slot_list = s; |
if (s->mode & MODE_PLAY) { |
if (s->mode & MODE_PLAY) { |