logo

oasis

Own branch of Oasis Linux (upstream: <https://git.sr.ht/~mcf/oasis/>) git clone https://anongit.hacktivis.me/git/oasis.git
commit: ed93a32292df4e93cd37bde7712db66da1b76d80
parent e4f1e4f50393a005ae1bb9a9ccbf02b8bd3c7670
Author: Michael Forney <mforney@mforney.org>
Date:   Tue, 31 Aug 2021 14:45:21 -0700

sndio: Port to tinyalsa

Diffstat:

Mpkg/sndio/gen.lua15+++++++--------
Apkg/sndio/patch/0003-alsa-Port-to-tinyalsa.patch1145+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpkg/sndio/ver2+-
3 files changed, 1153 insertions(+), 9 deletions(-)

diff --git a/pkg/sndio/gen.lua b/pkg/sndio/gen.lua @@ -4,12 +4,12 @@ cflags{ '-D _GNU_SOURCE', '-I $srcdir/libsndio', '-I $srcdir/bsd-compat', - '-isystem $builddir/pkg/alsa-lib/include', + '-isystem $builddir/pkg/tinyalsa/include', '-include $dir/config.h', } pkg.deps = { - 'pkg/alsa-lib/headers', + 'pkg/tinyalsa/headers', } pkg.hdrs = copy('$outdir/include', '$srcdir/libsndio', {'sndio.h'}) @@ -17,31 +17,30 @@ pkg.hdrs = copy('$outdir/include', '$srcdir/libsndio', {'sndio.h'}) local objs = objects[[ libsndio/( debug.c aucat.c - mio_aucat.c + mio.c mio_aucat.c sio_aucat.c sioctl.c sioctl_aucat.c ) bsd-compat/(issetugid.c strlcat.c strlcpy.c strtonum.c clock_gettime.c) - $builddir/pkg/alsa-lib/libasound.a + $builddir/pkg/tinyalsa/libtinyalsa.a ]] -- build mio.c and sio.c for sndiod with alsa support -for _, src in ipairs{'mio.c', 'mio_alsa.c', 'sio.c', 'sio_alsa.c'} do +for _, src in ipairs{'sio.c', 'sio_alsa.c'} do build('cc', '$outdir/sndiod/'..src..'.o', {'$srcdir/libsndio/'..src, '||', '$gendir/deps'}, { cflags='$cflags -D USE_ALSA', }) end -lib('libsndio.a', {objs, 'libsndio/mio.c', 'libsndio/sio.c'}) +lib('libsndio.a', {objs, 'libsndio/sio.c'}) exe('bin/sndiod', {objs, paths[[ sndiod/( abuf.c utils.c dev.c dev_sioctl.c dsp.c file.c listen.c midi.c miofile.c opt.c siofile.c sndiod.c sock.c - mio.c.o mio_alsa.c.o sio.c.o sio_alsa.c.o ) - $builddir/pkg/alsa-lib/libasound.a + $builddir/pkg/tinyalsa/libtinyalsa.a ]]}) file('bin/sndiod', '755', '$outdir/bin/sndiod') man{'sndiod/sndiod.8'} diff --git a/pkg/sndio/patch/0003-alsa-Port-to-tinyalsa.patch b/pkg/sndio/patch/0003-alsa-Port-to-tinyalsa.patch @@ -0,0 +1,1145 @@ +From 146d33f3eb2985677f39ad93d2864c5514f65985 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/sio_alsa.c | 741 ++++++++++++++++---------------------------- + 1 file changed, 259 insertions(+), 482 deletions(-) + +diff --git a/libsndio/sio_alsa.c b/libsndio/sio_alsa.c +index 7ae69c2..332b62e 100644 +--- a/libsndio/sio_alsa.c ++++ b/libsndio/sio_alsa.c +@@ -29,31 +29,29 @@ + #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; +@@ -101,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; +@@ -198,77 +162,41 @@ 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; ++ *rfmt = 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; +- } ++ if (le == ~0U) { ++ *rfmt = SIO_LE_NATIVE ? ++ PCM_FORMAT_S16_LE : ++ PCM_FORMAT_S16_BE; ++ } else if (le) ++ *rfmt = PCM_FORMAT_S16_LE; ++ else ++ *rfmt = PCM_FORMAT_S16_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; +- } ++ if (le == ~0U) { ++ *rfmt = SIO_LE_NATIVE ? ++ PCM_FORMAT_S24_LE : ++ PCM_FORMAT_S24_BE; ++ } else if (le) ++ *rfmt = PCM_FORMAT_S24_LE; ++ else ++ *rfmt = PCM_FORMAT_S24_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; +- } ++ if (le == ~0U) { ++ *rfmt = SIO_LE_NATIVE ? ++ PCM_FORMAT_S32_LE : ++ PCM_FORMAT_S32_BE; ++ } else if (le) ++ *rfmt = PCM_FORMAT_S32_LE; ++ else ++ *rfmt = PCM_FORMAT_S32_BE; + } else { + *rfmt = SIO_LE_NATIVE ? +- SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_S16_BE; ++ PCM_FORMAT_S16_LE : PCM_FORMAT_S16_BE; + } + } + +@@ -278,8 +206,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) { +@@ -299,42 +226,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 +@@ -355,12 +285,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; +@@ -371,11 +305,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); + } + +@@ -393,14 +330,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; + } +@@ -412,9 +347,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; + } +@@ -426,17 +361,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; + } +@@ -448,30 +383,26 @@ static int + sio_alsa_stop(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", pcm->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; + } +@@ -536,143 +467,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); ++ 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 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); +- 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; + } + } +@@ -692,13 +590,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; + } +@@ -743,178 +641,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; ++ struct pcm_config icfg, ocfg; + +- snd_pcm_hw_params_alloca(&ohwp); +- snd_pcm_sw_params_alloca(&oswp); +- snd_pcm_hw_params_alloca(&ihwp); +- snd_pcm_sw_params_alloca(&iswp); +- +- 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.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) +@@ -939,7 +731,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) { +@@ -958,7 +750,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) { +@@ -966,7 +758,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; +@@ -988,7 +780,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) { +@@ -1006,7 +798,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) { +@@ -1061,16 +853,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; +@@ -1082,100 +872,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; + } +@@ -1185,22 +961,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.32.0 + diff --git a/pkg/sndio/ver b/pkg/sndio/ver @@ -1 +1 @@ -1.8.1 r0 +1.8.1 r1