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 */
{
int rate, pmax, rmax;
struct sio_par par;
+ char encstr[ENCMAX];
struct slot *s;
if (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;
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);
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) {
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");