diff options
author | Alexandre Ratchov <[email protected]> | 2023-02-01 12:15:14 +0100 |
---|---|---|
committer | Paul Adenot <[email protected]> | 2023-02-01 15:54:51 +0100 |
commit | 0846b39f1fdc67aa444cc65b33ddc4b1c6bf565d (patch) | |
tree | 835c7ae9c4f7cc0c6db2532029058f3a2a8eeb1e | |
parent | 88585b669b51836c3817b80c113ac80c3b3d8b2a (diff) | |
download | cubeb-0846b39f1fdc67aa444cc65b33ddc4b1c6bf565d.tar.gz cubeb-0846b39f1fdc67aa444cc65b33ddc4b1c6bf565d.zip |
sndio: switch audio to 24-bit precision
-rw-r--r-- | src/cubeb_sndio.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/src/cubeb_sndio.c b/src/cubeb_sndio.c index 665110b..38e2435 100644 --- a/src/cubeb_sndio.c +++ b/src/cubeb_sndio.c @@ -68,7 +68,7 @@ struct cubeb_stream { struct sio_hdl * hdl; /* link us to sndio */ int mode; /* bitmap of SIO_{PLAY,REC} */ int active; /* cubec_start() called */ - int conv; /* need float->s16 conversion */ + int conv; /* need float->s24 conversion */ unsigned char * rbuf; /* rec data consumed from here */ unsigned char * pbuf; /* play data is prepared here */ unsigned int nfr; /* number of frames in ibuf and obuf */ @@ -99,33 +99,33 @@ s16_setvol(void * ptr, long nsamp, float volume) } static void -float_to_s16(void * ptr, long nsamp, float volume) +float_to_s24(void * ptr, long nsamp, float volume) { - int16_t * dst = ptr; + int32_t * dst = ptr; float * src = ptr; - float mult = volume * 32768; + float mult = volume * 8388608; int s; while (nsamp-- > 0) { s = lrintf(*(src++) * mult); - if (s < -32768) - s = -32768; - else if (s > 32767) - s = 32767; + if (s < -8388608) + s = -8388608; + else if (s > 8388607) + s = 8388607; *(dst++) = s; } } static void -s16_to_float(void * ptr, long nsamp) +s24_to_float(void * ptr, long nsamp) { - int16_t * src = ptr; + int32_t * src = ptr; float * dst = ptr; src += nsamp; dst += nsamp; while (nsamp-- > 0) - *(--dst) = (1. / 32768) * *(--src); + *(--dst) = (1. / 8388608) * *(--src); } static const char * @@ -213,7 +213,7 @@ sndio_mainloop(void * arg) } if ((s->mode & SIO_REC) && s->conv) - s16_to_float(s->rbuf, s->nfr * s->rchan); + s24_to_float(s->rbuf, s->nfr * s->rchan); /* invoke call-back, it returns less that s->nfr if done */ pthread_mutex_unlock(&s->mtx); @@ -244,7 +244,7 @@ sndio_mainloop(void * arg) if (s->mode & SIO_PLAY) { if (s->conv) - float_to_s16(s->pbuf, nfr * s->pchan, s->volume); + float_to_s24(s->pbuf, nfr * s->pchan, s->volume); else s16_setvol(s->pbuf, nfr * s->pchan, s->volume); } @@ -429,21 +429,25 @@ sndio_stream_init(cubeb * context, cubeb_stream ** stream, } WRAP(sio_initpar)(&wpar); wpar.sig = 1; - wpar.bits = 16; switch (format) { case CUBEB_SAMPLE_S16LE: wpar.le = 1; + wpar.bits = 16; break; case CUBEB_SAMPLE_S16BE: wpar.le = 0; + wpar.bits = 16; break; case CUBEB_SAMPLE_FLOAT32NE: wpar.le = SIO_LE_NATIVE; + wpar.bits = 24; + wpar.msb = 0; break; default: DPR("sndio_stream_init() unsupported format\n"); goto err; } + wpar.bps = SIO_BPS(wpar.bits); wpar.rate = rate; if (s->mode & SIO_REC) wpar.rchan = input_stream_params->channels; @@ -455,6 +459,7 @@ sndio_stream_init(cubeb * context, cubeb_stream ** stream, goto err; } if (rpar.bits != wpar.bits || rpar.le != wpar.le || rpar.sig != wpar.sig || + rpar.bps != wpar.bps || (wpar.bits < 8 * wpar.bps && rpar.msb != wpar.msb) || rpar.rate != wpar.rate || ((s->mode & SIO_REC) && rpar.rchan != wpar.rchan) || ((s->mode & SIO_PLAY) && rpar.pchan != wpar.pchan)) { |