summaryrefslogtreecommitdiff
path: root/usr.bin/aucat
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2024-03-22 06:20:49 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2024-03-22 06:20:49 +0000
commit7a61f8b9609e16b94688cd3508a025310c614043 (patch)
tree92c4cce91735211c5920e98cc751f1891d5f3bfd /usr.bin/aucat
parentc9f71038433f94d2d473d63d3230b254d07814bc (diff)
aucat: Allow any device sample encoding.
If the device doesn't support the aucat internal encoding, then setup a conversion layer instead of failing. This allows aucat to be used for audio equipment testing/debugging without involving the full sndiod processing chain.
Diffstat (limited to 'usr.bin/aucat')
-rw-r--r--usr.bin/aucat/aucat.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/usr.bin/aucat/aucat.c b/usr.bin/aucat/aucat.c
index 61898276f10..a9b59863d63 100644
--- a/usr.bin/aucat/aucat.c
+++ b/usr.bin/aucat/aucat.c
@@ -104,6 +104,9 @@ unsigned int dev_round; /* device block size */
int dev_rate; /* device sample rate (Hz) */
unsigned int dev_pchan, dev_rchan; /* play & rec channels count */
adata_t *dev_pbuf, *dev_rbuf; /* play & rec buffers */
+struct aparams dev_par; /* device sample format */
+struct conv dev_enc, dev_dec; /* format conversions */
+unsigned char *dev_encbuf, *dev_decbuf; /* buf for format conversions */
long long dev_pos; /* last MMC position in frames */
#define DEV_STOP 0 /* stopped */
#define DEV_START 1 /* started */
@@ -673,6 +676,7 @@ dev_open(char *dev, int mode, int bufsz, char *port)
{
int rate, pmax, rmax;
struct sio_par par;
+ char encstr[ENCMAX];
struct slot *s;
if (port) {
@@ -723,14 +727,11 @@ dev_open(char *dev, int mode, int bufsz, char *port)
log_puts(": couldn't set audio params\n");
return 0;
}
- if (par.bits != ADATA_BITS ||
- par.bps != sizeof(adata_t) ||
- (par.bps > 1 && par.le != SIO_LE_NATIVE) ||
- (par.bps * 8 > par.bits && par.msb)) {
- log_puts(dev_name);
- log_puts(": unsupported audio params\n");
- return 0;
- }
+ dev_par.bits = par.bits;
+ dev_par.bps = par.bps;
+ dev_par.sig = par.sig;
+ dev_par.le = par.le;
+ dev_par.msb = par.msb;
dev_mode = mode;
dev_rate = par.rate;
dev_bufsz = par.bufsz;
@@ -743,12 +744,24 @@ dev_open(char *dev, int mode, int bufsz, char *port)
dev_rchan = par.rchan;
dev_rbuf = allocbuf(dev_round, dev_rchan, sizeof(adata_t));
}
+ if (!aparams_native(&dev_par)) {
+ if (mode & SIO_PLAY) {
+ dev_encbuf = allocbuf(dev_round, dev_pchan, dev_par.bps);
+ enc_init(&dev_enc, &dev_par, dev_pchan);
+ }
+ if (mode & SIO_REC) {
+ dev_decbuf = allocbuf(dev_round, dev_rchan, dev_par.bps);
+ dec_init(&dev_dec, &dev_par, dev_rchan);
+ }
+ }
dev_pstate = DEV_STOP;
if (log_level >= 2) {
log_puts(dev_name);
log_puts(": ");
log_putu(dev_rate);
- log_puts("Hz");
+ log_puts("Hz, ");
+ aparams_enctostr(&dev_par, encstr);
+ log_puts(encstr);
if (dev_mode & SIO_PLAY) {
log_puts(", play 0:");
log_puti(dev_pchan - 1);
@@ -1145,8 +1158,8 @@ playrec_cycle(void)
if (dev_prime > 0)
dev_prime--;
else {
- todo = dev_round * dev_rchan * sizeof(adata_t);
- p = (unsigned char *)dev_rbuf;
+ todo = dev_round * dev_rchan * dev_par.bps;
+ p = dev_decbuf ? dev_decbuf : (unsigned char *)dev_rbuf;
while (todo > 0) {
n = sio_read(dev_sh, p, todo);
if (n == 0) {
@@ -1159,12 +1172,24 @@ playrec_cycle(void)
todo -= n;
}
rcnt = slot_list_copy(dev_round, dev_rchan, dev_rbuf);
+ if (dev_decbuf) {
+ dec_do(&dev_dec,
+ dev_decbuf, (unsigned char *)dev_rbuf,
+ dev_round);
+ }
}
}
if (dev_mode & SIO_PLAY) {
pcnt = slot_list_mix(dev_round, dev_pchan, dev_pbuf);
- todo = sizeof(adata_t) * dev_pchan * dev_round;
- n = sio_write(dev_sh, dev_pbuf, todo);
+ todo = dev_par.bps * dev_pchan * dev_round;
+ if (dev_encbuf) {
+ enc_do(&dev_enc,
+ (unsigned char *)dev_pbuf, dev_encbuf,
+ dev_round);
+ p = dev_encbuf;
+ } else
+ p = (unsigned char *)dev_pbuf;
+ n = sio_write(dev_sh, p, todo);
if (n == 0) {
log_puts(dev_name);
log_puts(": failed to write to device\n");