0003-alsa-Port-to-tinyalsa.patch (31813B)
- From 39ec20119841c84500e589fee15c10e9fe6c0c97 Mon Sep 17 00:00:00 2001
- From: Michael Forney <mforney@mforney.org>
- Date: Tue, 31 Aug 2021 14:30:07 -0700
- Subject: [PATCH] alsa: Port to tinyalsa
- ---
- libsndio/debug.c | 2 +-
- libsndio/sio_alsa.c | 747 +++++++++++++++-----------------------------
- 2 files changed, 247 insertions(+), 502 deletions(-)
- diff --git a/libsndio/debug.c b/libsndio/debug.c
- index 304975a..40fdc92 100644
- --- a/libsndio/debug.c
- +++ b/libsndio/debug.c
- @@ -35,7 +35,7 @@ _sndio_debug_init(void)
- if (_sndio_debug < 0) {
- dbg = issetugid() ? NULL : getenv("SNDIO_DEBUG");
- - if (!dbg || sscanf(dbg, "%u", &_sndio_debug) != 1)
- + if (!dbg || sscanf(dbg, "%d", &_sndio_debug) != 1)
- _sndio_debug = 0;
- }
- }
- diff --git a/libsndio/sio_alsa.c b/libsndio/sio_alsa.c
- index 6107617..e460bf6 100644
- --- a/libsndio/sio_alsa.c
- +++ b/libsndio/sio_alsa.c
- @@ -29,31 +29,28 @@
- #include <string.h>
- #include <unistd.h>
- #include <values.h>
- -#include <alsa/asoundlib.h>
- +#include <tinyalsa/asoundlib.h>
- #include "debug.h"
- #include "sio_priv.h"
- #include "bsd-compat.h"
- -#define DEVNAME_PREFIX "hw:"
- -
- #ifdef DEBUG
- -static snd_output_t *output = NULL;
- -#define DALSA(str, err) fprintf(stderr, "%s: %s\n", str, snd_strerror(err))
- +#define DALSA(str, pcm) fprintf(stderr, "%s: %s\n", str, pcm_get_error(pcm))
- #else
- -#define DALSA(str, err) do {} while (0)
- +#define DALSA(str, pcm) do {} while (0)
- #endif
- struct sio_alsa_hdl {
- struct sio_hdl sio;
- struct sio_par par;
- - char *devname;
- - snd_pcm_t *opcm;
- - snd_pcm_t *ipcm;
- + struct pcm_params *opar;
- + struct pcm_params *ipar;
- + struct pcm *opcm;
- + struct pcm *ipcm;
- unsigned ibpf, obpf; /* bytes per frame */
- int iused, oused; /* frames used in hardware fifos */
- int idelta, odelta; /* position reported to client */
- - int nfds, infds, onfds;
- int running;
- int events;
- int ipartial, opartial;
- @@ -102,90 +99,56 @@ static unsigned int cap_rates[] = {
- 8000, 11025, 12000, 16000, 22050, 24000,
- 32000, 44100, 48000, 64000, 88200, 96000
- };
- -static snd_pcm_format_t cap_fmts[] = {
- +static enum pcm_format cap_fmts[] = {
- /* XXX add s24le3 and s24be3 */
- - SND_PCM_FORMAT_S32_LE, SND_PCM_FORMAT_S32_BE,
- - SND_PCM_FORMAT_S24_LE, SND_PCM_FORMAT_S24_BE,
- - SND_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_S16_BE,
- - SND_PCM_FORMAT_U8
- + PCM_FORMAT_S32_LE, PCM_FORMAT_S32_BE,
- + PCM_FORMAT_S24_LE, PCM_FORMAT_S24_BE,
- + PCM_FORMAT_S16_LE, PCM_FORMAT_S16_BE,
- + PCM_FORMAT_S8
- };
- /*
- * convert ALSA format to sio_par encoding
- */
- static int
- -sio_alsa_fmttopar(struct sio_alsa_hdl *hdl, snd_pcm_format_t fmt,
- +sio_alsa_fmttopar(struct sio_alsa_hdl *hdl, enum pcm_format fmt,
- unsigned int *bits, unsigned int *sig, unsigned int *le)
- {
- switch (fmt) {
- - case SND_PCM_FORMAT_U8:
- - *bits = 8;
- - *sig = 0;
- - break;
- - case SND_PCM_FORMAT_S8:
- + case PCM_FORMAT_S8:
- *bits = 8;
- *sig = 1;
- break;
- - case SND_PCM_FORMAT_S16_LE:
- + case PCM_FORMAT_S16_LE:
- *bits = 16;
- *sig = 1;
- *le = 1;
- break;
- - case SND_PCM_FORMAT_S16_BE:
- + case PCM_FORMAT_S16_BE:
- *bits = 16;
- *sig = 1;
- *le = 0;
- break;
- - case SND_PCM_FORMAT_U16_LE:
- - *bits = 16;
- - *sig = 0;
- - *le = 1;
- - break;
- - case SND_PCM_FORMAT_U16_BE:
- - *bits = 16;
- - *sig = 0;
- - *le = 0;
- - break;
- - case SND_PCM_FORMAT_S24_LE:
- + case PCM_FORMAT_S24_LE:
- *bits = 24;
- *sig = 1;
- *le = 1;
- break;
- - case SND_PCM_FORMAT_S24_BE:
- + case PCM_FORMAT_S24_BE:
- *bits = 24;
- *sig = 1;
- *le = 0;
- break;
- - case SND_PCM_FORMAT_U24_LE:
- - *bits = 24;
- - *sig = 0;
- - *le = 1;
- - break;
- - case SND_PCM_FORMAT_U24_BE:
- - *bits = 24;
- - *sig = 0;
- - *le = 0;
- - break;
- - case SND_PCM_FORMAT_S32_LE:
- + case PCM_FORMAT_S32_LE:
- *bits = 32;
- *sig = 1;
- *le = 1;
- break;
- - case SND_PCM_FORMAT_S32_BE:
- + case PCM_FORMAT_S32_BE:
- *bits = 32;
- *sig = 1;
- *le = 0;
- break;
- - case SND_PCM_FORMAT_U32_LE:
- - *bits = 32;
- - *sig = 0;
- - *le = 1;
- - break;
- - case SND_PCM_FORMAT_U32_BE:
- - *bits = 32;
- - *sig = 0;
- - *le = 0;
- - break;
- default:
- DPRINTF("sio_alsa_fmttopar: 0x%x: unsupported format\n", fmt);
- hdl->sio.eof = 1;
- @@ -199,78 +162,19 @@ sio_alsa_fmttopar(struct sio_alsa_hdl *hdl, snd_pcm_format_t fmt,
- * convert sio_par encoding to ALSA format
- */
- static void
- -sio_alsa_enctofmt(struct sio_alsa_hdl *hdl, snd_pcm_format_t *rfmt,
- +sio_alsa_enctofmt(struct sio_alsa_hdl *hdl, enum pcm_format *rfmt,
- unsigned int bits, unsigned int sig, unsigned int le)
- {
- - if (bits == 8) {
- - if (sig == ~0U || !sig)
- - *rfmt = SND_PCM_FORMAT_U8;
- - else
- - *rfmt = SND_PCM_FORMAT_S8;
- - } else if (bits == 16) {
- - if (sig == ~0U || sig) {
- - if (le == ~0U) {
- - *rfmt = SIO_LE_NATIVE ?
- - SND_PCM_FORMAT_S16_LE :
- - SND_PCM_FORMAT_S16_BE;
- - } else if (le)
- - *rfmt = SND_PCM_FORMAT_S16_LE;
- - else
- - *rfmt = SND_PCM_FORMAT_S16_BE;
- - } else {
- - if (le == ~0U) {
- - *rfmt = SIO_LE_NATIVE ?
- - SND_PCM_FORMAT_U16_LE :
- - SND_PCM_FORMAT_U16_BE;
- - } else if (le)
- - *rfmt = SND_PCM_FORMAT_U16_LE;
- - else
- - *rfmt = SND_PCM_FORMAT_U16_BE;
- - }
- - } else if (bits == 24) {
- - if (sig == ~0U || sig) {
- - if (le == ~0U) {
- - *rfmt = SIO_LE_NATIVE ?
- - SND_PCM_FORMAT_S24_LE :
- - SND_PCM_FORMAT_S24_BE;
- - } else if (le)
- - *rfmt = SND_PCM_FORMAT_S24_LE;
- - else
- - *rfmt = SND_PCM_FORMAT_S24_BE;
- - } else {
- - if (le == ~0U) {
- - *rfmt = SIO_LE_NATIVE ?
- - SND_PCM_FORMAT_U24_LE :
- - SND_PCM_FORMAT_U24_BE;
- - } else if (le)
- - *rfmt = SND_PCM_FORMAT_U24_LE;
- - else
- - *rfmt = SND_PCM_FORMAT_U24_BE;
- - }
- - } else if (bits == 32) {
- - if (sig == ~0U || sig) {
- - if (le == ~0U) {
- - *rfmt = SIO_LE_NATIVE ?
- - SND_PCM_FORMAT_S32_LE :
- - SND_PCM_FORMAT_S32_BE;
- - } else if (le)
- - *rfmt = SND_PCM_FORMAT_S32_LE;
- - else
- - *rfmt = SND_PCM_FORMAT_S32_BE;
- - } else {
- - if (le == ~0U) {
- - *rfmt = SIO_LE_NATIVE ?
- - SND_PCM_FORMAT_U32_LE :
- - SND_PCM_FORMAT_U32_BE;
- - } else if (le)
- - *rfmt = SND_PCM_FORMAT_U32_LE;
- - else
- - *rfmt = SND_PCM_FORMAT_U32_BE;
- - }
- - } else {
- - *rfmt = SIO_LE_NATIVE ?
- - SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_S16_BE;
- - }
- + if (le == ~0U)
- + le = SIO_LE_NATIVE;
- + if (bits == 8)
- + *rfmt = PCM_FORMAT_S8;
- + else if (bits == 24)
- + *rfmt = le ? PCM_FORMAT_S24_LE : PCM_FORMAT_S24_BE;
- + else if (bits == 32)
- + *rfmt = le ? PCM_FORMAT_S32_LE : PCM_FORMAT_S32_BE;
- + else
- + *rfmt = le ? PCM_FORMAT_S16_LE : PCM_FORMAT_S16_BE;
- }
- struct sio_hdl *
- @@ -279,8 +183,7 @@ _sio_alsa_open(const char *str, unsigned mode, int nbio)
- const char *p;
- struct sio_alsa_hdl *hdl;
- struct sio_par par;
- - size_t len;
- - int err;
- + unsigned card, dev;
- p = _sndio_parsetype(str, "rsnd");
- if (p == NULL) {
- @@ -300,42 +203,45 @@ _sio_alsa_open(const char *str, unsigned mode, int nbio)
- return NULL;
- _sio_create(&hdl->sio, &sio_alsa_ops, mode, nbio);
- -#ifdef DEBUG
- - err = snd_output_stdio_attach(&output, stderr, 0);
- - if (err < 0)
- - DALSA("couldn't attach to stderr", err);
- -#endif
- - if (strcmp(p, "default") == 0)
- - p = "0";
- - len = strlen(p);
- - hdl->devname = malloc(len + sizeof(DEVNAME_PREFIX));
- - if (hdl->devname == NULL)
- - goto bad_free_hdl;
- - memcpy(hdl->devname, DEVNAME_PREFIX, sizeof(DEVNAME_PREFIX) - 1);
- - memcpy(hdl->devname + sizeof(DEVNAME_PREFIX) - 1, p, len + 1);
- + if (strcmp(p, "default") == 0) {
- + card = 0;
- + dev = 0;
- + } else {
- + switch (sscanf(p, "%u,%u", &card, &dev)) {
- + case 1:
- + dev = 0;
- + break;
- + case 2:
- + break;
- + default:
- + DPRINTF("invalid device name\n");
- + }
- + }
- if (mode & SIO_PLAY) {
- - err = snd_pcm_open(&hdl->opcm, hdl->devname,
- - SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
- - if (err < 0) {
- - DALSA("couldn't open play stream", err);
- - goto bad_free;
- + hdl->opar = pcm_params_get(card, dev, PCM_OUT);
- + if (hdl->opar == NULL) {
- + DPRINTF("couldn't get play params\n");
- + goto bad_free_hdl;
- + }
- + hdl->opcm = pcm_open(card, dev, PCM_OUT | PCM_NONBLOCK, NULL);
- + if (!pcm_is_ready(hdl->opcm)) {
- + DALSA("couldn't open play stream", hdl->opcm);
- + goto bad_free_opar;
- }
- }
- if (mode & SIO_REC) {
- - err = snd_pcm_open(&hdl->ipcm, hdl->devname,
- - SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
- - if (err < 0) {
- - DALSA("couldn't open rec stream", err);
- + hdl->ipar = pcm_params_get(card, dev, PCM_IN);
- + if (hdl->ipar == NULL) {
- + DPRINTF("couldn't get rec params\n");
- goto bad_free_opcm;
- }
- + hdl->ipcm = pcm_open(card, dev, PCM_IN | PCM_NONBLOCK, NULL);
- + if (!pcm_is_ready(hdl->ipcm)) {
- + DALSA("couldn't open rec stream", hdl->ipcm);
- + goto bad_free_ipar;
- + }
- }
- - /*
- - * snd_pcm_poll_descriptors_count returns a small value
- - * that grows later, after the stream is started
- - */
- - hdl->nfds = SIO_MAXNFDS;
- -
- /*
- * Default parameters may not be compatible with libsndio (eg. mulaw
- * encodings, different playback and recording parameters, etc...), so
- @@ -356,12 +262,16 @@ _sio_alsa_open(const char *str, unsigned mode, int nbio)
- return (struct sio_hdl *)hdl;
- bad_free_ipcm:
- if (mode & SIO_REC)
- - snd_pcm_close(hdl->ipcm);
- + pcm_close(hdl->ipcm);
- +bad_free_ipar:
- + if (mode & SIO_REC)
- + free(hdl->ipar);
- bad_free_opcm:
- if (mode & SIO_PLAY)
- - snd_pcm_close(hdl->opcm);
- -bad_free:
- - free(hdl->devname);
- + pcm_close(hdl->opcm);
- +bad_free_opar:
- + if (mode & SIO_PLAY)
- + free(hdl->opar);
- bad_free_hdl:
- free(hdl);
- return NULL;
- @@ -372,11 +282,14 @@ sio_alsa_close(struct sio_hdl *sh)
- {
- struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
- - if (hdl->sio.mode & SIO_PLAY)
- - snd_pcm_close(hdl->opcm);
- - if (hdl->sio.mode & SIO_REC)
- - snd_pcm_close(hdl->ipcm);
- - free(hdl->devname);
- + if (hdl->sio.mode & SIO_PLAY) {
- + free(hdl->opar);
- + pcm_close(hdl->opcm);
- + }
- + if (hdl->sio.mode & SIO_REC) {
- + free(hdl->ipar);
- + pcm_close(hdl->ipcm);
- + }
- free(hdl);
- }
- @@ -394,14 +307,12 @@ sio_alsa_start(struct sio_hdl *sh)
- hdl->oused = 0;
- hdl->idelta = 0;
- hdl->odelta = 0;
- - hdl->infds = 0;
- - hdl->onfds = 0;
- hdl->running = 0;
- if (hdl->sio.mode & SIO_PLAY) {
- - err = snd_pcm_prepare(hdl->opcm);
- + err = pcm_prepare(hdl->opcm);
- if (err < 0) {
- - DALSA("couldn't prepare play stream", err);
- + DALSA("couldn't prepare play stream", hdl->opcm);
- hdl->sio.eof = 1;
- return 0;
- }
- @@ -413,9 +324,9 @@ sio_alsa_start(struct sio_hdl *sh)
- hdl->opartial = 0;
- }
- if (hdl->sio.mode & SIO_REC) {
- - err = snd_pcm_prepare(hdl->ipcm);
- + err = pcm_prepare(hdl->ipcm);
- if (err < 0) {
- - DALSA("couldn't prepare rec stream", err);
- + DALSA("couldn't prepare rec stream", hdl->ipcm);
- hdl->sio.eof = 1;
- return 0;
- }
- @@ -427,17 +338,17 @@ sio_alsa_start(struct sio_hdl *sh)
- hdl->ipartial = 0;
- }
- if ((hdl->sio.mode & SIO_PLAY) && (hdl->sio.mode & SIO_REC)) {
- - err = snd_pcm_link(hdl->ipcm, hdl->opcm);
- + err = pcm_link(hdl->ipcm, hdl->opcm);
- if (err < 0) {
- - DALSA("couldn't link streams", err);
- + DALSA("couldn't link streams", hdl->ipcm);
- hdl->sio.eof = 1;
- return 0;
- }
- }
- if (!(hdl->sio.mode & SIO_PLAY)) {
- - err = snd_pcm_start(hdl->ipcm);
- + err = pcm_start(hdl->ipcm);
- if (err < 0) {
- - DALSA("couldn't start rec stream", err);
- + DALSA("couldn't start rec stream", hdl->ipcm);
- hdl->sio.eof = 1;
- return 0;
- }
- @@ -449,30 +360,26 @@ static int
- sio_alsa_flush(struct sio_hdl *sh)
- {
- struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
- - int err;
- if (hdl->sio.mode & SIO_PLAY) {
- - err = snd_pcm_drop(hdl->opcm);
- - if (err < 0) {
- - DALSA("couldn't stop play stream", err);
- + if (pcm_stop(hdl->opcm) != 0) {
- + DALSA("couldn't stop play stream", hdl->opcm);
- hdl->sio.eof = 1;
- return 0;
- }
- free(hdl->otmpbuf);
- }
- if (hdl->sio.mode & SIO_REC) {
- - err = snd_pcm_drop(hdl->ipcm);
- - if (err < 0) {
- - DALSA("couldn't stop rec stream", err);
- + if (pcm_stop(hdl->ipcm) != 0) {
- + DALSA("couldn't stop rec stream", hdl->ipcm);
- hdl->sio.eof = 1;
- return 0;
- }
- free(hdl->itmpbuf);
- }
- if ((hdl->sio.mode & SIO_PLAY) && (hdl->sio.mode & SIO_REC)) {
- - err = snd_pcm_unlink(hdl->ipcm);
- - if (err < 0) {
- - DALSA("couldn't unlink streams", err);
- + if (pcm_unlink(hdl->ipcm) != 0) {
- + DALSA("couldn't unlink streams", hdl->ipcm);
- hdl->sio.eof = 1;
- return 0;
- }
- @@ -537,143 +444,110 @@ sio_alsa_xrun(struct sio_alsa_hdl *hdl)
- }
- static int
- -sio_alsa_setpar_hw(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwp,
- - snd_pcm_format_t *reqfmt, unsigned int *rate, unsigned int *chans,
- - snd_pcm_uframes_t *round, unsigned int *periods)
- +sio_alsa_setpar_hw(struct pcm *pcm, struct pcm_params *par,
- + struct pcm_config *cfg)
- {
- - static snd_pcm_format_t fmts[] = {
- - SND_PCM_FORMAT_S32_LE, SND_PCM_FORMAT_S32_BE,
- - SND_PCM_FORMAT_U32_LE, SND_PCM_FORMAT_U32_BE,
- - SND_PCM_FORMAT_S24_LE, SND_PCM_FORMAT_S24_BE,
- - SND_PCM_FORMAT_U24_LE, SND_PCM_FORMAT_U24_BE,
- - SND_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_S16_BE,
- - SND_PCM_FORMAT_U16_LE, SND_PCM_FORMAT_U16_BE,
- - SND_PCM_FORMAT_U8, SND_PCM_FORMAT_S8
- + static enum pcm_format fmts[] = {
- + PCM_FORMAT_S32_LE, PCM_FORMAT_S32_BE,
- + PCM_FORMAT_S24_LE, PCM_FORMAT_S24_BE,
- + PCM_FORMAT_S16_LE, PCM_FORMAT_S16_BE,
- + PCM_FORMAT_S8
- };
- - int i, err, dir = 0;
- - unsigned req_rate, min_periods = 2;
- + int i, err;
- + unsigned req_rate;
- + unsigned min, max;
- - req_rate = *rate;
- + /* XXX: HW_FREE */
- - err = snd_pcm_hw_free(pcm);
- - if (err < 0) {
- - DALSA("couldn't reset hw configuration", err);
- - return 0;
- - }
- - err = snd_pcm_hw_params_any(pcm, hwp);
- - if (err < 0) {
- - DALSA("couldn't init pars", err);
- - return 0;
- - }
- - err = snd_pcm_hw_params_set_access(pcm, hwp,
- - SND_PCM_ACCESS_RW_INTERLEAVED);
- - if (err < 0) {
- - DALSA("couldn't set interleaved access", err);
- - return 0;
- - }
- - err = snd_pcm_hw_params_test_format(pcm, hwp, *reqfmt);
- - if (err < 0) {
- + if (pcm_params_format_test(par, cfg->format) == 0) {
- for (i = 0; ; i++) {
- - if (i == sizeof(fmts) / sizeof(snd_pcm_format_t)) {
- + if (i == sizeof(fmts) / sizeof(fmts[0])) {
- DPRINTF("no known format found\n");
- return 0;
- }
- - err = snd_pcm_hw_params_test_format(pcm, hwp, fmts[i]);
- - if (err)
- + if (pcm_params_format_test(par, fmts[i]) == 0)
- continue;
- - *reqfmt = fmts[i];
- + cfg->format = fmts[i];
- break;
- }
- }
- - err = snd_pcm_hw_params_set_format(pcm, hwp, *reqfmt);
- - if (err < 0) {
- - DALSA("couldn't set fmt", err);
- - return 0;
- - }
- - err = snd_pcm_hw_params_set_rate_resample(pcm, hwp, 0);
- - if (err < 0) {
- - DALSA("couldn't turn resampling off", err);
- - return 0;
- - }
- - err = snd_pcm_hw_params_set_rate_near(pcm, hwp, rate, 0);
- - if (err < 0) {
- - DALSA("couldn't set rate", err);
- - return 0;
- - }
- - err = snd_pcm_hw_params_set_channels_near(pcm, hwp, chans);
- - if (err < 0) {
- - DALSA("couldn't set channel count", err);
- - return 0;
- - }
- - err = snd_pcm_hw_params_set_periods_integer(pcm, hwp);
- - if (err < 0) {
- - DALSA("couldn't set periods to integer", err);
- - return 0;
- - }
- - err = snd_pcm_hw_params_set_periods_min(pcm, hwp, &min_periods, NULL);
- - if (err < 0) {
- - DALSA("couldn't set minimum periods", err);
- - return 0;
- - }
- - err = snd_pcm_hw_params_set_period_size_integer(pcm, hwp);
- - if (err < 0) {
- - DALSA("couldn't set period to integer", err);
- - return 0;
- - }
- -
- - *round = *round * *rate / req_rate;
- - *round = (*round + 31) & ~31;
- - err = snd_pcm_hw_params_set_period_size_near(pcm, hwp, round, &dir);
- - if (err < 0) {
- - DALSA("couldn't set period size failed", err);
- - return 0;
- - }
- - err = snd_pcm_hw_params_set_periods_near(pcm, hwp, periods, &dir);
- - if (err < 0) {
- - DALSA("couldn't set period count", err);
- - return 0;
- - }
- - err = snd_pcm_hw_params(pcm, hwp);
- + req_rate = cfg->rate;
- + min = pcm_params_get_min(par, PCM_PARAM_RATE);
- + if (cfg->rate < min)
- + cfg->rate = min;
- + max = pcm_params_get_max(par, PCM_PARAM_RATE);
- + if (cfg->rate > max)
- + cfg->rate = max;
- +
- + min = pcm_params_get_min(par, PCM_PARAM_CHANNELS);
- + if (cfg->channels < min)
- + cfg->channels = min;
- + max = pcm_params_get_max(par, PCM_PARAM_CHANNELS);
- + if (cfg->channels > max)
- + cfg->channels = max;
- +
- + cfg->period_size = cfg->period_size * cfg->rate / req_rate;
- + cfg->period_size = (cfg->period_size + 31) & ~31;
- +
- + min = pcm_params_get_min(par, PCM_PARAM_PERIOD_SIZE);
- + if (min < 2)
- + min = 2;
- + if (cfg->period_size < min)
- + cfg->period_size = min;
- + max = pcm_params_get_max(par, PCM_PARAM_PERIOD_SIZE);
- + if (cfg->period_size > max)
- + cfg->period_size = max;
- +
- + min = pcm_params_get_min(par, PCM_PARAM_PERIODS);
- + if (cfg->period_count < min)
- + cfg->period_count = min;
- + max = pcm_params_get_max(par, PCM_PARAM_PERIODS);
- + if (cfg->period_count > max)
- + cfg->period_count = max;
- +
- + cfg->start_threshold = 0;
- + cfg->stop_threshold = cfg->period_count * cfg->period_size;
- + cfg->avail_min = 1;
- + cfg->silence_size = 0;
- + cfg->silence_threshold = 0;
- +
- + /* XXX: period_event=1, silence?, silence_threshold? */
- +
- + err = pcm_set_config(pcm, cfg);
- if (err < 0) {
- - DALSA("couldn't commit params", err);
- + DALSA("couldn't set config", pcm);
- return 0;
- }
- return 1;
- }
- static int
- -sio_alsa_getcap_hw(snd_pcm_t *pcm, int *rates, int *fmts, int *chans)
- +sio_alsa_getcap_hw(struct pcm_params *par, int *rates, int *fmts, int *chans)
- {
- int i, err;
- - snd_pcm_hw_params_t *hwp;
- -
- - snd_pcm_hw_params_alloca(&hwp);
- -
- - err = snd_pcm_hw_params_any(pcm, hwp);
- - if (err < 0) {
- - DALSA("sio_alsa_trypar: couldn't init pars", err);
- - return 0;
- - }
- + unsigned min, max;
- *fmts = 0;
- for (i = 0; i < CAP_NFMTS; i++) {
- - err = snd_pcm_hw_params_test_format(pcm, hwp, cap_fmts[i]);
- + err = pcm_params_format_test(par, cap_fmts[i]);
- if (err == 0) {
- *fmts |= 1 << i;
- }
- }
- *rates = 0;
- + min = pcm_params_get_min(par, PCM_PARAM_RATE);
- + max = pcm_params_get_max(par, PCM_PARAM_RATE);
- for (i = 0; i < CAP_NRATES; i++) {
- - err = snd_pcm_hw_params_test_rate(pcm, hwp, cap_rates[i], 0);
- - if (err == 0) {
- + if (min <= cap_rates[i] && cap_rates[i] <= max) {
- *rates |= 1 << i;
- }
- }
- *chans = 0;
- + min = pcm_params_get_min(par, PCM_PARAM_CHANNELS);
- + max = pcm_params_get_max(par, PCM_PARAM_CHANNELS);
- for (i = 0; i < CAP_NCHANS; i++) {
- - err = snd_pcm_hw_params_test_channels(pcm, hwp, cap_chans[i]);
- - if (err == 0) {
- + if (min <= cap_chans[i] && cap_chans[i] <= max) {
- *chans |= 1 << i;
- }
- }
- @@ -693,13 +567,13 @@ sio_alsa_getcap(struct sio_hdl *sh, struct sio_cap *cap)
- irates = orates = ifmts = ofmts = ichans = ochans = 0;
- if (hdl->sio.mode & SIO_PLAY) {
- - if (!sio_alsa_getcap_hw(hdl->opcm,
- + if (!sio_alsa_getcap_hw(hdl->opar,
- &orates, &ofmts, &ochans)) {
- return 0;
- }
- }
- if (hdl->sio.mode & SIO_REC) {
- - if (!sio_alsa_getcap_hw(hdl->ipcm,
- + if (!sio_alsa_getcap_hw(hdl->ipar,
- &irates, &ifmts, &ichans)) {
- return 0;
- }
- @@ -711,7 +585,7 @@ sio_alsa_getcap(struct sio_hdl *sh, struct sio_cap *cap)
- &cap->enc[i].sig,
- &cap->enc[i].le);
- cap->enc[i].bps = SIO_BPS(cap->enc[0].bits);
- - cap->enc[i].msb = 1;
- + cap->enc[i].msb = 0;
- }
- for (i = 0; i < CAP_NRATES; i++) {
- cap->rate[i] = cap_rates[i];
- @@ -744,186 +618,72 @@ static int
- sio_alsa_setpar(struct sio_hdl *sh, struct sio_par *par)
- {
- struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
- - snd_pcm_hw_params_t *ohwp, *ihwp;
- - snd_pcm_sw_params_t *oswp, *iswp;
- - snd_pcm_uframes_t iround, oround;
- - snd_pcm_format_t ifmt, ofmt;
- - unsigned int iperiods, operiods;
- - unsigned irate, orate;
- - int err;
- -
- - snd_pcm_hw_params_alloca(&ohwp);
- - snd_pcm_sw_params_alloca(&oswp);
- - snd_pcm_hw_params_alloca(&ihwp);
- - snd_pcm_sw_params_alloca(&iswp);
- + struct pcm_config icfg, ocfg;
- - sio_alsa_enctofmt(hdl, &ifmt, par->bits, par->sig, par->le);
- - irate = (par->rate == ~0U) ? 48000 : par->rate;
- + sio_alsa_enctofmt(hdl, &icfg.format, par->bits, par->sig, par->le);
- + icfg.rate = (par->rate == ~0U) ? 48000 : par->rate;
- if (par->appbufsz != ~0U) {
- - iround = (par->round != ~0U) ?
- + icfg.period_size = (par->round != ~0U) ?
- par->round : (par->appbufsz + 1) / 2;
- - iperiods = par->appbufsz / iround;
- - if (iperiods < 2)
- - iperiods = 2;
- + icfg.period_count = par->appbufsz / icfg.period_size;
- + if (icfg.period_count < 2)
- + icfg.period_count = 2;
- } else if (par->round != ~0U) {
- - iround = par->round;
- - iperiods = 2;
- + icfg.period_size = par->round;
- + icfg.period_count = 2;
- } else {
- - iperiods = 2;
- - iround = irate / 100;
- + icfg.period_count = 2;
- + icfg.period_size = icfg.rate / 100;
- }
- if (hdl->sio.mode & SIO_REC) {
- hdl->par.rchan = par->rchan;
- - if (!sio_alsa_setpar_hw(hdl->ipcm, ihwp,
- - &ifmt, &irate, &hdl->par.rchan,
- - &iround, &iperiods)) {
- + if (!sio_alsa_setpar_hw(hdl->ipcm, hdl->ipar, &icfg)) {
- hdl->sio.eof = 1;
- return 0;
- }
- }
- - ofmt = ifmt;
- - orate = irate;
- - oround = iround;
- - operiods = iperiods;
- + ocfg = icfg;
- if (hdl->sio.mode & SIO_PLAY) {
- hdl->par.pchan = par->pchan;
- - if (!sio_alsa_setpar_hw(hdl->opcm, ohwp,
- - &ofmt, &orate, &hdl->par.pchan,
- - &oround, &operiods)) {
- + if (!sio_alsa_setpar_hw(hdl->opcm, hdl->opar, &ocfg)) {
- hdl->sio.eof = 1;
- return 0;
- }
- - if (!(hdl->sio.mode & SIO_REC)) {
- - ifmt = ofmt;
- - irate = orate;
- - iround = oround;
- - iperiods = operiods;
- - }
- + if (!(hdl->sio.mode & SIO_REC))
- + icfg = ocfg;
- }
- DPRINTFN(2, "ofmt = %u, orate = %u, oround = %u, operiods = %u\n",
- - ofmt, orate, (unsigned int)oround, operiods);
- + ocfg.format, ocfg.rate, ocfg.period_size, ocfg.period_count);
- DPRINTFN(2, "ifmt = %u, irate = %u, iround = %u, iperiods = %u\n",
- - ifmt, irate, (unsigned int)iround, iperiods);
- + icfg.format, icfg.rate, icfg.period_size, icfg.period_count);
- - if (ifmt != ofmt) {
- + if (icfg.format != ocfg.format) {
- DPRINTF("play and rec formats differ\n");
- hdl->sio.eof = 1;
- return 0;
- }
- - if (irate != orate) {
- + if (icfg.rate != ocfg.rate) {
- DPRINTF("play and rec rates differ\n");
- hdl->sio.eof = 1;
- return 0;
- }
- - if (iround != oround) {
- + if (icfg.period_size != ocfg.period_size) {
- DPRINTF("play and rec block sizes differ\n");
- hdl->sio.eof = 1;
- return 0;
- }
- - if (!sio_alsa_fmttopar(hdl, ifmt,
- + if (!sio_alsa_fmttopar(hdl, icfg.format,
- &hdl->par.bits, &hdl->par.sig, &hdl->par.le))
- return 0;
- - hdl->par.msb = 1;
- + hdl->par.msb = 0;
- hdl->par.bps = SIO_BPS(hdl->par.bits);
- - hdl->par.rate = orate;
- - hdl->par.round = oround;
- - hdl->par.bufsz = oround * operiods;
- + hdl->par.rate = ocfg.rate;
- + hdl->par.round = ocfg.period_size;
- + hdl->par.bufsz = ocfg.period_size * ocfg.period_count;
- hdl->par.appbufsz = hdl->par.bufsz;
- - /* software params */
- -
- - if (hdl->sio.mode & SIO_REC) {
- - err = snd_pcm_sw_params_current(hdl->ipcm, iswp);
- - if (err < 0) {
- - DALSA("couldn't get current rec params", err);
- - hdl->sio.eof = 1;
- - return 0;
- - }
- - err = snd_pcm_sw_params_set_start_threshold(hdl->ipcm,
- - iswp, 0);
- - if (err < 0) {
- - DALSA("couldn't set rec start threshold", err);
- - hdl->sio.eof = 1;
- - return 0;
- - }
- - err = snd_pcm_sw_params_set_stop_threshold(hdl->ipcm,
- - iswp, hdl->par.bufsz);
- - if (err < 0) {
- - DALSA("couldn't set rec stop threshold", err);
- - hdl->sio.eof = 1;
- - return 0;
- - }
- - err = snd_pcm_sw_params_set_avail_min(hdl->ipcm,
- - iswp, 1);
- - if (err < 0) {
- - DALSA("couldn't set rec avail min", err);
- - hdl->sio.eof = 1;
- - return 0;
- - }
- - err = snd_pcm_sw_params_set_period_event(hdl->ipcm, iswp, 1);
- - if (err < 0) {
- - DALSA("couldn't set rec period event", err);
- - hdl->sio.eof = 1;
- - return 0;
- - }
- - err = snd_pcm_sw_params(hdl->ipcm, iswp);
- - if (err < 0) {
- - DALSA("couldn't commit rec sw params", err);
- - hdl->sio.eof = 1;
- - return 0;
- - }
- - }
- - if (hdl->sio.mode & SIO_PLAY) {
- - err = snd_pcm_sw_params_current(hdl->opcm, oswp);
- - if (err < 0) {
- - DALSA("couldn't get current play params", err);
- - hdl->sio.eof = 1;
- - return 0;
- - }
- - err = snd_pcm_sw_params_set_start_threshold(hdl->opcm,
- - oswp, hdl->par.bufsz - hdl->par.round);
- - if (err < 0) {
- - DALSA("couldn't set play start threshold", err);
- - hdl->sio.eof = 1;
- - return 0;
- - }
- - err = snd_pcm_sw_params_set_stop_threshold(hdl->opcm,
- - oswp, hdl->par.bufsz);
- - if (err < 0) {
- - DALSA("couldn't set play stop threshold", err);
- - hdl->sio.eof = 1;
- - return 0;
- - }
- - err = snd_pcm_sw_params_set_avail_min(hdl->opcm,
- - oswp, 1);
- - if (err < 0) {
- - DALSA("couldn't set play avail min", err);
- - hdl->sio.eof = 1;
- - return 0;
- - }
- - err = snd_pcm_sw_params_set_period_event(hdl->opcm, oswp, 1);
- - if (err < 0) {
- - DALSA("couldn't set play period event", err);
- - hdl->sio.eof = 1;
- - return 0;
- - }
- - err = snd_pcm_sw_params(hdl->opcm, oswp);
- - if (err < 0) {
- - DALSA("couldn't commit play sw params", err);
- - hdl->sio.eof = 1;
- - return 0;
- - }
- - }
- -#ifdef DEBUG
- - if (_sndio_debug >= 2) {
- - if (hdl->sio.mode & SIO_REC)
- - snd_pcm_dump(hdl->ipcm, output);
- - if (hdl->sio.mode & SIO_PLAY)
- - snd_pcm_dump(hdl->opcm, output);
- - }
- -#endif
- return 1;
- }
- @@ -940,7 +700,7 @@ static size_t
- sio_alsa_read(struct sio_hdl *sh, void *buf, size_t len)
- {
- struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
- - snd_pcm_sframes_t n;
- + int n;
- size_t todo;
- if (hdl->ipartial > 0) {
- @@ -959,7 +719,7 @@ sio_alsa_read(struct sio_hdl *sh, void *buf, size_t len)
- todo = len / hdl->ibpf;
- if (todo == 0)
- return 0;
- - while ((n = snd_pcm_readi(hdl->ipcm, buf, todo)) < 0) {
- + while ((n = pcm_readi(hdl->ipcm, buf, todo)) < 0) {
- if (n == -EINTR)
- continue;
- if (n == -EPIPE || n == -ESTRPIPE) {
- @@ -967,7 +727,7 @@ sio_alsa_read(struct sio_hdl *sh, void *buf, size_t len)
- return 0;
- }
- if (n != -EAGAIN) {
- - DALSA("couldn't read data", n);
- + DALSA("couldn't read data", hdl->ipcm);
- hdl->sio.eof = 1;
- }
- return 0;
- @@ -989,7 +749,7 @@ static size_t
- sio_alsa_write(struct sio_hdl *sh, const void *buf, size_t len)
- {
- struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
- - snd_pcm_sframes_t n;
- + int n;
- size_t todo;
- if (len < hdl->obpf || hdl->opartial > 0) {
- @@ -1007,7 +767,7 @@ sio_alsa_write(struct sio_hdl *sh, const void *buf, size_t len)
- todo = len / hdl->obpf;
- if (todo == 0)
- return 0;
- - while ((n = snd_pcm_writei(hdl->opcm, buf, todo)) < 0) {
- + while ((n = pcm_writei(hdl->opcm, buf, todo)) < 0) {
- if (n == -EINTR)
- continue;
- if (n == -ESTRPIPE || n == -EPIPE) {
- @@ -1015,7 +775,7 @@ sio_alsa_write(struct sio_hdl *sh, const void *buf, size_t len)
- return 0;
- }
- if (n != -EAGAIN) {
- - DALSA("couldn't write data", n);
- + DALSA("couldn't write data", hdl->opcm);
- hdl->sio.eof = 1;
- }
- return 0;
- @@ -1062,16 +822,14 @@ sio_alsa_onmove(struct sio_alsa_hdl *hdl)
- static int
- sio_alsa_nfds(struct sio_hdl *sh)
- {
- - struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
- -
- - return hdl->nfds;
- + return 2;
- }
- static int
- sio_alsa_pollfd(struct sio_hdl *sh, struct pollfd *pfd, int events)
- {
- struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
- - int i;
- + int i, nfds;
- if (hdl->sio.eof)
- return 0;
- @@ -1083,100 +841,86 @@ sio_alsa_pollfd(struct sio_hdl *sh, struct pollfd *pfd, int events)
- hdl->events &= ~POLLIN;
- if (!hdl->sio.started)
- hdl->events = 0;
- - memset(pfd, 0, sizeof(struct pollfd) * hdl->nfds);
- - hdl->onfds = hdl->infds = 0;
- + memset(pfd, 0, sizeof(struct pollfd) * 2);
- + nfds = 0;
- if (hdl->events & POLLOUT) {
- if (!hdl->running &&
- - snd_pcm_state(hdl->opcm) == SND_PCM_STATE_RUNNING)
- + pcm_state(hdl->opcm) == PCM_STATE_RUNNING)
- sio_alsa_onmove(hdl);
- - hdl->onfds = snd_pcm_poll_descriptors(hdl->opcm,
- - pfd, hdl->nfds);
- - if (hdl->onfds < 0) {
- - DALSA("couldn't poll play descriptors",
- - hdl->onfds);
- - hdl->sio.eof = 1;
- - return 0;
- - }
- +
- + pfd[0].fd = pcm_get_poll_fd(hdl->opcm);
- + pfd[0].events = POLLOUT;
- + nfds++;
- }
- if (hdl->events & POLLIN) {
- if (!hdl->running &&
- - snd_pcm_state(hdl->ipcm) == SND_PCM_STATE_RUNNING)
- + pcm_state(hdl->ipcm) == PCM_STATE_RUNNING)
- sio_alsa_onmove(hdl);
- - hdl->infds = snd_pcm_poll_descriptors(hdl->ipcm,
- - pfd + hdl->onfds, hdl->nfds - hdl->onfds);
- - if (hdl->infds < 0) {
- - DALSA("couldn't poll rec descriptors",
- - hdl->infds);
- - hdl->sio.eof = 1;
- - return 0;
- - }
- +
- + pfd[nfds].fd = pcm_get_poll_fd(hdl->ipcm);
- + pfd[nfds].events = POLLIN;
- + nfds++;
- }
- - DPRINTFN(4, "sio_alsa_pollfd: events = %x, nfds = %d + %d\n",
- - events, hdl->onfds, hdl->infds);
- + DPRINTFN(4, "sio_alsa_pollfd: events = %x, nfds = %d\n",
- + events, nfds);
- - for (i = 0; i < hdl->onfds + hdl->infds; i++) {
- + for (i = 0; i < nfds; i++) {
- DPRINTFN(4, "sio_alsa_pollfd: pfds[%d].events = %x\n",
- i, pfd[i].events);
- }
- - return hdl->onfds + hdl->infds;
- + return nfds;
- }
- int
- sio_alsa_revents(struct sio_hdl *sh, struct pollfd *pfd)
- {
- struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
- - snd_pcm_sframes_t iused, oavail, oused;
- - snd_pcm_state_t istate, ostate;
- - unsigned short revents, r;
- - int nfds, err, i;
- + struct timespec ts;
- + unsigned iused, oavail, oused;
- + int istate, ostate;
- + unsigned short revents;
- + int nfds, i;
- if (hdl->sio.eof)
- return POLLHUP;
- - for (i = 0; i < hdl->onfds + hdl->infds; i++) {
- + nfds = 0;
- + if (hdl->events & POLLOUT)
- + nfds++;
- + if (hdl->events & POLLIN)
- + nfds++;
- +
- + for (i = 0; i < nfds; i++) {
- DPRINTFN(4, "sio_alsa_revents: pfds[%d].revents = %x\n",
- i, pfd[i].revents);
- }
- revents = nfds = 0;
- if (hdl->events & POLLOUT) {
- - err = snd_pcm_poll_descriptors_revents(hdl->opcm,
- - pfd, hdl->onfds, &r);
- - if (err < 0) {
- - DALSA("couldn't get play events", err);
- - hdl->sio.eof = 1;
- - return POLLHUP;
- - }
- - revents |= r;
- - nfds += hdl->onfds;
- + revents |= pfd[0].revents;
- + ++nfds;
- }
- if (hdl->events & POLLIN) {
- - err = snd_pcm_poll_descriptors_revents(hdl->ipcm,
- - pfd + nfds, hdl->infds, &r);
- - if (err < 0) {
- - DALSA("couldn't get rec events", err);
- - hdl->sio.eof = 1;
- - return POLLHUP;
- - }
- - revents |= r;
- - nfds += hdl->infds;
- + revents |= pfd[nfds].revents;
- + ++nfds;
- }
- if (hdl->sio.mode & SIO_PLAY) {
- - ostate = snd_pcm_state(hdl->opcm);
- - if (ostate == SND_PCM_STATE_XRUN) {
- + ostate = pcm_state(hdl->opcm);
- + if (ostate == PCM_STATE_XRUN) {
- if (!sio_alsa_xrun(hdl))
- return POLLHUP;
- return 0;
- }
- - if (ostate == SND_PCM_STATE_RUNNING ||
- - ostate == SND_PCM_STATE_PREPARED) {
- - oavail = snd_pcm_avail_update(hdl->opcm);
- - if (oavail < 0) {
- + if (ostate == PCM_STATE_RUNNING ||
- + ostate == PCM_STATE_PREPARED) {
- + if (pcm_get_htimestamp(hdl->opcm, &oavail, &ts) != 0) {
- + /*
- if (oavail == -EPIPE || oavail == -ESTRPIPE) {
- if (!sio_alsa_xrun(hdl))
- return POLLHUP;
- return 0;
- }
- - DALSA("couldn't get play buffer ptr", oavail);
- + */
- + DPRINTF("couldn't get play buffer ptr\n");
- hdl->sio.eof = 1;
- return POLLHUP;
- }
- @@ -1186,22 +930,23 @@ sio_alsa_revents(struct sio_hdl *sh, struct pollfd *pfd)
- }
- }
- if (hdl->sio.mode & SIO_REC) {
- - istate = snd_pcm_state(hdl->ipcm);
- - if (istate == SND_PCM_STATE_XRUN) {
- + istate = pcm_state(hdl->ipcm);
- + if (istate == PCM_STATE_XRUN) {
- if (!sio_alsa_xrun(hdl))
- return POLLHUP;
- return 0;
- }
- - if (istate == SND_PCM_STATE_RUNNING ||
- - istate == SND_PCM_STATE_PREPARED) {
- - iused = snd_pcm_avail_update(hdl->ipcm);
- - if (iused < 0) {
- + if (istate == PCM_STATE_RUNNING ||
- + istate == PCM_STATE_PREPARED) {
- + if (pcm_get_htimestamp(hdl->ipcm, &iused, &ts) != 0) {
- + /*
- if (iused == -EPIPE || iused == -ESTRPIPE) {
- if (!sio_alsa_xrun(hdl))
- return POLLHUP;
- return 0;
- }
- - DALSA("couldn't get rec buffer ptr", iused);
- + */
- + DPRINTF("couldn't get rec buffer ptr\n");
- hdl->sio.eof = 1;
- return POLLHUP;
- }
- --
- 2.37.3