master hovercats/oakiss / pkg / sndio / patch / 0003-alsa-Port-to-tinyalsa.patch
   1From 39ec20119841c84500e589fee15c10e9fe6c0c97 Mon Sep 17 00:00:00 2001
   2From: Michael Forney <mforney@mforney.org>
   3Date: Tue, 31 Aug 2021 14:30:07 -0700
   4Subject: [PATCH] alsa: Port to tinyalsa
   5
   6---
   7 libsndio/debug.c    |   2 +-
   8 libsndio/sio_alsa.c | 747 +++++++++++++++-----------------------------
   9 2 files changed, 247 insertions(+), 502 deletions(-)
  10
  11diff --git a/libsndio/debug.c b/libsndio/debug.c
  12index 304975a..40fdc92 100644
  13--- a/libsndio/debug.c
  14+++ b/libsndio/debug.c
  15@@ -35,7 +35,7 @@ _sndio_debug_init(void)
  16 
  17 	if (_sndio_debug < 0) {
  18 		dbg = issetugid() ? NULL : getenv("SNDIO_DEBUG");
  19-		if (!dbg || sscanf(dbg, "%u", &_sndio_debug) != 1)
  20+		if (!dbg || sscanf(dbg, "%d", &_sndio_debug) != 1)
  21 			_sndio_debug = 0;
  22 	}
  23 }
  24diff --git a/libsndio/sio_alsa.c b/libsndio/sio_alsa.c
  25index 6107617..e460bf6 100644
  26--- a/libsndio/sio_alsa.c
  27+++ b/libsndio/sio_alsa.c
  28@@ -29,31 +29,28 @@
  29 #include <string.h>
  30 #include <unistd.h>
  31 #include <values.h>
  32-#include <alsa/asoundlib.h>
  33+#include <tinyalsa/asoundlib.h>
  34 
  35 #include "debug.h"
  36 #include "sio_priv.h"
  37 #include "bsd-compat.h"
  38 
  39-#define DEVNAME_PREFIX "hw:"
  40-
  41 #ifdef DEBUG
  42-static snd_output_t *output = NULL;
  43-#define DALSA(str, err) fprintf(stderr, "%s: %s\n", str, snd_strerror(err))
  44+#define DALSA(str, pcm) fprintf(stderr, "%s: %s\n", str, pcm_get_error(pcm))
  45 #else
  46-#define DALSA(str, err) do {} while (0)
  47+#define DALSA(str, pcm) do {} while (0)
  48 #endif
  49 
  50 struct sio_alsa_hdl {
  51 	struct sio_hdl sio;
  52 	struct sio_par par;
  53-	char *devname;
  54-	snd_pcm_t *opcm;
  55-	snd_pcm_t *ipcm;
  56+	struct pcm_params *opar;
  57+	struct pcm_params *ipar;
  58+	struct pcm *opcm;
  59+	struct pcm *ipcm;
  60 	unsigned ibpf, obpf;		/* bytes per frame */
  61 	int iused, oused;		/* frames used in hardware fifos */
  62 	int idelta, odelta;		/* position reported to client */
  63-	int nfds, infds, onfds;
  64 	int running;
  65 	int events;
  66 	int ipartial, opartial;
  67@@ -102,90 +99,56 @@ static unsigned int cap_rates[] = {
  68 	 8000, 11025, 12000, 16000, 22050, 24000,
  69 	32000, 44100, 48000, 64000, 88200, 96000
  70 };
  71-static snd_pcm_format_t cap_fmts[] = {
  72+static enum pcm_format cap_fmts[] = {
  73 	/* XXX add s24le3 and s24be3 */
  74-	SND_PCM_FORMAT_S32_LE,	SND_PCM_FORMAT_S32_BE,
  75-	SND_PCM_FORMAT_S24_LE,	SND_PCM_FORMAT_S24_BE,
  76-	SND_PCM_FORMAT_S16_LE,	SND_PCM_FORMAT_S16_BE,
  77-	SND_PCM_FORMAT_U8
  78+	PCM_FORMAT_S32_LE,	PCM_FORMAT_S32_BE,
  79+	PCM_FORMAT_S24_LE,	PCM_FORMAT_S24_BE,
  80+	PCM_FORMAT_S16_LE,	PCM_FORMAT_S16_BE,
  81+	PCM_FORMAT_S8
  82 };
  83 
  84 /*
  85  * convert ALSA format to sio_par encoding
  86  */
  87 static int
  88-sio_alsa_fmttopar(struct sio_alsa_hdl *hdl, snd_pcm_format_t fmt,
  89+sio_alsa_fmttopar(struct sio_alsa_hdl *hdl, enum pcm_format fmt,
  90     unsigned int *bits, unsigned int *sig, unsigned int *le)
  91 {
  92 	switch (fmt) {
  93-	case SND_PCM_FORMAT_U8:
  94-		*bits = 8;
  95-		*sig = 0;
  96-		break;
  97-	case SND_PCM_FORMAT_S8:
  98+	case PCM_FORMAT_S8:
  99 		*bits = 8;
 100 		*sig = 1;
 101 		break;
 102-	case SND_PCM_FORMAT_S16_LE:
 103+	case PCM_FORMAT_S16_LE:
 104 		*bits = 16;
 105 		*sig = 1;
 106 		*le = 1;
 107 		break;
 108-	case SND_PCM_FORMAT_S16_BE:
 109+	case PCM_FORMAT_S16_BE:
 110 		*bits = 16;
 111 		*sig = 1;
 112 		*le = 0;
 113 		break;
 114-	case SND_PCM_FORMAT_U16_LE:
 115-		*bits = 16;
 116-		*sig = 0;
 117-		*le = 1;
 118-		break;
 119-	case SND_PCM_FORMAT_U16_BE:
 120-		*bits = 16;
 121-		*sig = 0;
 122-		*le = 0;
 123-		break;
 124-	case SND_PCM_FORMAT_S24_LE:
 125+	case PCM_FORMAT_S24_LE:
 126 		*bits = 24;
 127 		*sig = 1;
 128 		*le = 1;
 129 		break;
 130-	case SND_PCM_FORMAT_S24_BE:
 131+	case PCM_FORMAT_S24_BE:
 132 		*bits = 24;
 133 		*sig = 1;
 134 		*le = 0;
 135 		break;
 136-	case SND_PCM_FORMAT_U24_LE:
 137-		*bits = 24;
 138-		*sig = 0;
 139-		*le = 1;
 140-		break;
 141-	case SND_PCM_FORMAT_U24_BE:
 142-		*bits = 24;
 143-		*sig = 0;
 144-		*le = 0;
 145-		break;
 146-	case SND_PCM_FORMAT_S32_LE:
 147+	case PCM_FORMAT_S32_LE:
 148 		*bits = 32;
 149 		*sig = 1;
 150 		*le = 1;
 151 		break;
 152-	case SND_PCM_FORMAT_S32_BE:
 153+	case PCM_FORMAT_S32_BE:
 154 		*bits = 32;
 155 		*sig = 1;
 156 		*le = 0;
 157 		break;
 158-	case SND_PCM_FORMAT_U32_LE:
 159-		*bits = 32;
 160-		*sig = 0;
 161-		*le = 1;
 162-		break;
 163-	case SND_PCM_FORMAT_U32_BE:
 164-		*bits = 32;
 165-		*sig = 0;
 166-		*le = 0;
 167-		break;
 168 	default:
 169 		DPRINTF("sio_alsa_fmttopar: 0x%x: unsupported format\n", fmt);
 170 		hdl->sio.eof = 1;
 171@@ -199,78 +162,19 @@ sio_alsa_fmttopar(struct sio_alsa_hdl *hdl, snd_pcm_format_t fmt,
 172  * convert sio_par encoding to ALSA format
 173  */
 174 static void
 175-sio_alsa_enctofmt(struct sio_alsa_hdl *hdl, snd_pcm_format_t *rfmt,
 176+sio_alsa_enctofmt(struct sio_alsa_hdl *hdl, enum pcm_format *rfmt,
 177     unsigned int bits, unsigned int sig, unsigned int le)
 178 {
 179-	if (bits == 8) {
 180-		if (sig == ~0U || !sig)
 181-			*rfmt = SND_PCM_FORMAT_U8;
 182-		else
 183-			*rfmt = SND_PCM_FORMAT_S8;
 184-	} else if (bits == 16) {
 185-		if (sig == ~0U || sig) {
 186-			if (le == ~0U) {
 187-				*rfmt = SIO_LE_NATIVE ?
 188-				    SND_PCM_FORMAT_S16_LE :
 189-				    SND_PCM_FORMAT_S16_BE;
 190-			} else if (le)
 191-				*rfmt = SND_PCM_FORMAT_S16_LE;
 192-			else
 193-				*rfmt = SND_PCM_FORMAT_S16_BE;
 194-		} else {
 195-			if (le == ~0U) {
 196-				*rfmt = SIO_LE_NATIVE ?
 197-				    SND_PCM_FORMAT_U16_LE :
 198-				    SND_PCM_FORMAT_U16_BE;
 199-			} else if (le)
 200-				*rfmt = SND_PCM_FORMAT_U16_LE;
 201-			else
 202-				*rfmt = SND_PCM_FORMAT_U16_BE;
 203-		}
 204-	} else if (bits == 24) {
 205-		if (sig == ~0U || sig) {
 206-			if (le == ~0U) {
 207-				*rfmt = SIO_LE_NATIVE ?
 208-				    SND_PCM_FORMAT_S24_LE :
 209-				    SND_PCM_FORMAT_S24_BE;
 210-			 } else if (le)
 211-				*rfmt = SND_PCM_FORMAT_S24_LE;
 212-			else
 213-				*rfmt = SND_PCM_FORMAT_S24_BE;
 214-		} else {
 215-			if (le == ~0U) {
 216-				*rfmt = SIO_LE_NATIVE ?
 217-				    SND_PCM_FORMAT_U24_LE :
 218-				    SND_PCM_FORMAT_U24_BE;
 219-			} else if (le)
 220-				*rfmt = SND_PCM_FORMAT_U24_LE;
 221-			else
 222-				*rfmt = SND_PCM_FORMAT_U24_BE;
 223-		}
 224-	} else if (bits == 32) {
 225-		if (sig == ~0U || sig) {
 226-			if (le == ~0U) {
 227-				*rfmt = SIO_LE_NATIVE ?
 228-				    SND_PCM_FORMAT_S32_LE :
 229-				    SND_PCM_FORMAT_S32_BE;
 230-			 } else if (le)
 231-				*rfmt = SND_PCM_FORMAT_S32_LE;
 232-			else
 233-				*rfmt = SND_PCM_FORMAT_S32_BE;
 234-		} else {
 235-			if (le == ~0U) {
 236-				*rfmt = SIO_LE_NATIVE ?
 237-				    SND_PCM_FORMAT_U32_LE :
 238-				    SND_PCM_FORMAT_U32_BE;
 239-			} else if (le)
 240-				*rfmt = SND_PCM_FORMAT_U32_LE;
 241-			else
 242-				*rfmt = SND_PCM_FORMAT_U32_BE;
 243-		}
 244-	} else {
 245-		*rfmt = SIO_LE_NATIVE ?
 246-		    SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_S16_BE;
 247-	}
 248+	if (le == ~0U)
 249+		le = SIO_LE_NATIVE;
 250+	if (bits == 8)
 251+		*rfmt = PCM_FORMAT_S8;
 252+	else if (bits == 24)
 253+		*rfmt = le ? PCM_FORMAT_S24_LE : PCM_FORMAT_S24_BE;
 254+	else if (bits == 32)
 255+		*rfmt = le ? PCM_FORMAT_S32_LE : PCM_FORMAT_S32_BE;
 256+	else
 257+		*rfmt = le ? PCM_FORMAT_S16_LE : PCM_FORMAT_S16_BE;
 258 }
 259 
 260 struct sio_hdl *
 261@@ -279,8 +183,7 @@ _sio_alsa_open(const char *str, unsigned mode, int nbio)
 262 	const char *p;
 263 	struct sio_alsa_hdl *hdl;
 264 	struct sio_par par;
 265-	size_t len;
 266-	int err;
 267+	unsigned card, dev;
 268 
 269 	p = _sndio_parsetype(str, "rsnd");
 270 	if (p == NULL) {
 271@@ -300,42 +203,45 @@ _sio_alsa_open(const char *str, unsigned mode, int nbio)
 272 		return NULL;
 273 	_sio_create(&hdl->sio, &sio_alsa_ops, mode, nbio);
 274 
 275-#ifdef DEBUG
 276-	err = snd_output_stdio_attach(&output, stderr, 0);
 277-	if (err < 0)
 278-		DALSA("couldn't attach to stderr", err);
 279-#endif
 280-	if (strcmp(p, "default") == 0)
 281-		p = "0";
 282-	len = strlen(p);
 283-	hdl->devname = malloc(len + sizeof(DEVNAME_PREFIX));
 284-	if (hdl->devname == NULL)
 285-		goto bad_free_hdl;
 286-	memcpy(hdl->devname, DEVNAME_PREFIX, sizeof(DEVNAME_PREFIX) - 1);
 287-	memcpy(hdl->devname + sizeof(DEVNAME_PREFIX) - 1, p, len + 1);
 288+	if (strcmp(p, "default") == 0) {
 289+		card = 0;
 290+		dev = 0;
 291+	} else {
 292+		switch (sscanf(p, "%u,%u", &card, &dev)) {
 293+		case 1:
 294+			dev = 0;
 295+			break;
 296+		case 2:
 297+			break;
 298+		default:
 299+			DPRINTF("invalid device name\n");
 300+		}
 301+	}
 302 	if (mode & SIO_PLAY) {
 303-		err = snd_pcm_open(&hdl->opcm, hdl->devname,
 304-		    SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
 305-		if (err < 0) {
 306-			DALSA("couldn't open play stream", err);
 307-			goto bad_free;
 308+		hdl->opar = pcm_params_get(card, dev, PCM_OUT);
 309+		if (hdl->opar == NULL) {
 310+			DPRINTF("couldn't get play params\n");
 311+			goto bad_free_hdl;
 312+		}
 313+		hdl->opcm = pcm_open(card, dev, PCM_OUT | PCM_NONBLOCK, NULL);
 314+		if (!pcm_is_ready(hdl->opcm)) {
 315+			DALSA("couldn't open play stream", hdl->opcm);
 316+			goto bad_free_opar;
 317 		}
 318 	}
 319 	if (mode & SIO_REC) {
 320-		err = snd_pcm_open(&hdl->ipcm, hdl->devname,
 321-		    SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
 322-		if (err < 0) {
 323-			DALSA("couldn't open rec stream", err);
 324+		hdl->ipar = pcm_params_get(card, dev, PCM_IN);
 325+		if (hdl->ipar == NULL) {
 326+			DPRINTF("couldn't get rec params\n");
 327 			goto bad_free_opcm;
 328 		}
 329+		hdl->ipcm = pcm_open(card, dev, PCM_IN | PCM_NONBLOCK, NULL);
 330+		if (!pcm_is_ready(hdl->ipcm)) {
 331+			DALSA("couldn't open rec stream", hdl->ipcm);
 332+			goto bad_free_ipar;
 333+		}
 334 	}
 335 
 336-	/*
 337-	 * snd_pcm_poll_descriptors_count returns a small value
 338-	 * that grows later, after the stream is started
 339-	 */
 340-	hdl->nfds = SIO_MAXNFDS;
 341-
 342 	/*
 343 	 * Default parameters may not be compatible with libsndio (eg. mulaw
 344 	 * encodings, different playback and recording parameters, etc...), so
 345@@ -356,12 +262,16 @@ _sio_alsa_open(const char *str, unsigned mode, int nbio)
 346 	return (struct sio_hdl *)hdl;
 347 bad_free_ipcm:
 348 	if (mode & SIO_REC)
 349-		snd_pcm_close(hdl->ipcm);
 350+		pcm_close(hdl->ipcm);
 351+bad_free_ipar:
 352+	if (mode & SIO_REC)
 353+		free(hdl->ipar);
 354 bad_free_opcm:
 355 	if (mode & SIO_PLAY)
 356-		snd_pcm_close(hdl->opcm);
 357-bad_free:
 358-	free(hdl->devname);
 359+		pcm_close(hdl->opcm);
 360+bad_free_opar:
 361+	if (mode & SIO_PLAY)
 362+		free(hdl->opar);
 363 bad_free_hdl:
 364 	free(hdl);
 365 	return NULL;
 366@@ -372,11 +282,14 @@ sio_alsa_close(struct sio_hdl *sh)
 367 {
 368 	struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
 369 
 370-	if (hdl->sio.mode & SIO_PLAY)
 371-		snd_pcm_close(hdl->opcm);
 372-	if (hdl->sio.mode & SIO_REC)
 373-		snd_pcm_close(hdl->ipcm);
 374-	free(hdl->devname);
 375+	if (hdl->sio.mode & SIO_PLAY) {
 376+		free(hdl->opar);
 377+		pcm_close(hdl->opcm);
 378+	}
 379+	if (hdl->sio.mode & SIO_REC) {
 380+		free(hdl->ipar);
 381+		pcm_close(hdl->ipcm);
 382+	}
 383 	free(hdl);
 384 }
 385 
 386@@ -394,14 +307,12 @@ sio_alsa_start(struct sio_hdl *sh)
 387 	hdl->oused = 0;
 388 	hdl->idelta = 0;
 389 	hdl->odelta = 0;
 390-	hdl->infds = 0;
 391-	hdl->onfds = 0;
 392 	hdl->running = 0;
 393 
 394 	if (hdl->sio.mode & SIO_PLAY) {
 395-		err = snd_pcm_prepare(hdl->opcm);
 396+		err = pcm_prepare(hdl->opcm);
 397 		if (err < 0) {
 398-			DALSA("couldn't prepare play stream", err);
 399+			DALSA("couldn't prepare play stream", hdl->opcm);
 400 			hdl->sio.eof = 1;
 401 			return 0;
 402 		}
 403@@ -413,9 +324,9 @@ sio_alsa_start(struct sio_hdl *sh)
 404 		hdl->opartial = 0;
 405 	}
 406 	if (hdl->sio.mode & SIO_REC) {
 407-		err = snd_pcm_prepare(hdl->ipcm);
 408+		err = pcm_prepare(hdl->ipcm);
 409 		if (err < 0) {
 410-			DALSA("couldn't prepare rec stream", err);
 411+			DALSA("couldn't prepare rec stream", hdl->ipcm);
 412 			hdl->sio.eof = 1;
 413 			return 0;
 414 		}
 415@@ -427,17 +338,17 @@ sio_alsa_start(struct sio_hdl *sh)
 416 		hdl->ipartial = 0;
 417 	}
 418 	if ((hdl->sio.mode & SIO_PLAY) && (hdl->sio.mode & SIO_REC)) {
 419-		err = snd_pcm_link(hdl->ipcm, hdl->opcm);
 420+		err = pcm_link(hdl->ipcm, hdl->opcm);
 421 		if (err < 0) {
 422-			DALSA("couldn't link streams", err);
 423+			DALSA("couldn't link streams", hdl->ipcm);
 424 			hdl->sio.eof = 1;
 425 			return 0;
 426 		}
 427 	}
 428 	if (!(hdl->sio.mode & SIO_PLAY)) {
 429-		err = snd_pcm_start(hdl->ipcm);
 430+		err = pcm_start(hdl->ipcm);
 431 		if (err < 0) {
 432-			DALSA("couldn't start rec stream", err);
 433+			DALSA("couldn't start rec stream", hdl->ipcm);
 434 			hdl->sio.eof = 1;
 435 			return 0;
 436 		}
 437@@ -449,30 +360,26 @@ static int
 438 sio_alsa_flush(struct sio_hdl *sh)
 439 {
 440 	struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
 441-	int err;
 442 
 443 	if (hdl->sio.mode & SIO_PLAY) {
 444-		err = snd_pcm_drop(hdl->opcm);
 445-		if (err < 0) {
 446-			DALSA("couldn't stop play stream", err);
 447+		if (pcm_stop(hdl->opcm) != 0) {
 448+			DALSA("couldn't stop play stream", hdl->opcm);
 449 			hdl->sio.eof = 1;
 450 			return 0;
 451 		}
 452 		free(hdl->otmpbuf);
 453 	}
 454 	if (hdl->sio.mode & SIO_REC) {
 455-		err = snd_pcm_drop(hdl->ipcm);
 456-		if (err < 0) {
 457-			DALSA("couldn't stop rec stream", err);
 458+		if (pcm_stop(hdl->ipcm) != 0) {
 459+			DALSA("couldn't stop rec stream", hdl->ipcm);
 460 			hdl->sio.eof = 1;
 461 			return 0;
 462 		}
 463 		free(hdl->itmpbuf);
 464 	}
 465 	if ((hdl->sio.mode & SIO_PLAY) && (hdl->sio.mode & SIO_REC)) {
 466-		err = snd_pcm_unlink(hdl->ipcm);
 467-		if (err < 0) {
 468-			DALSA("couldn't unlink streams", err);
 469+		if (pcm_unlink(hdl->ipcm) != 0) {
 470+			DALSA("couldn't unlink streams", hdl->ipcm);
 471 			hdl->sio.eof = 1;
 472 			return 0;
 473 		}
 474@@ -537,143 +444,110 @@ sio_alsa_xrun(struct sio_alsa_hdl *hdl)
 475 }
 476 
 477 static int
 478-sio_alsa_setpar_hw(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwp,
 479-    snd_pcm_format_t *reqfmt, unsigned int *rate, unsigned int *chans,
 480-    snd_pcm_uframes_t *round, unsigned int *periods)
 481+sio_alsa_setpar_hw(struct pcm *pcm, struct pcm_params *par,
 482+    struct pcm_config *cfg)
 483 {
 484-	static snd_pcm_format_t fmts[] = {
 485-		SND_PCM_FORMAT_S32_LE,	SND_PCM_FORMAT_S32_BE,
 486-		SND_PCM_FORMAT_U32_LE,	SND_PCM_FORMAT_U32_BE,
 487-		SND_PCM_FORMAT_S24_LE,	SND_PCM_FORMAT_S24_BE,
 488-		SND_PCM_FORMAT_U24_LE,	SND_PCM_FORMAT_U24_BE,
 489-		SND_PCM_FORMAT_S16_LE,	SND_PCM_FORMAT_S16_BE,
 490-		SND_PCM_FORMAT_U16_LE,	SND_PCM_FORMAT_U16_BE,
 491-		SND_PCM_FORMAT_U8,	SND_PCM_FORMAT_S8
 492+	static enum pcm_format fmts[] = {
 493+		PCM_FORMAT_S32_LE,	PCM_FORMAT_S32_BE,
 494+		PCM_FORMAT_S24_LE,	PCM_FORMAT_S24_BE,
 495+		PCM_FORMAT_S16_LE,	PCM_FORMAT_S16_BE,
 496+		PCM_FORMAT_S8
 497 	};
 498-	int i, err, dir = 0;
 499-	unsigned req_rate, min_periods = 2;
 500+	int i, err;
 501+	unsigned req_rate;
 502+	unsigned min, max;
 503 
 504-	req_rate = *rate;
 505+	/* XXX: HW_FREE */
 506 
 507-	err = snd_pcm_hw_free(pcm);
 508-	if (err < 0) {
 509-		DALSA("couldn't reset hw configuration", err);
 510-		return 0;
 511-	}
 512-	err = snd_pcm_hw_params_any(pcm, hwp);
 513-	if (err < 0) {
 514-		DALSA("couldn't init pars", err);
 515-		return 0;
 516-	}
 517-	err = snd_pcm_hw_params_set_access(pcm, hwp,
 518-	    SND_PCM_ACCESS_RW_INTERLEAVED);
 519-	if (err < 0) {
 520-		DALSA("couldn't set interleaved access", err);
 521-		return 0;
 522-	}
 523-	err = snd_pcm_hw_params_test_format(pcm, hwp, *reqfmt);
 524-	if (err < 0) {
 525+	if (pcm_params_format_test(par, cfg->format) == 0) {
 526 		for (i = 0; ; i++) {
 527-			if (i == sizeof(fmts) / sizeof(snd_pcm_format_t)) {
 528+			if (i == sizeof(fmts) / sizeof(fmts[0])) {
 529 				DPRINTF("no known format found\n");
 530 				return 0;
 531 			}
 532-			err = snd_pcm_hw_params_test_format(pcm, hwp, fmts[i]);
 533-			if (err)
 534+			if (pcm_params_format_test(par, fmts[i]) == 0)
 535 				continue;
 536-			*reqfmt = fmts[i];
 537+			cfg->format = fmts[i];
 538 			break;
 539 		}
 540 	}
 541-	err = snd_pcm_hw_params_set_format(pcm, hwp, *reqfmt);
 542-	if (err < 0) {
 543-		DALSA("couldn't set fmt", err);
 544-		return 0;
 545-	}
 546-	err = snd_pcm_hw_params_set_rate_resample(pcm, hwp, 0);
 547-	if (err < 0) {
 548-		DALSA("couldn't turn resampling off", err);
 549-		return 0;
 550-	}
 551-	err = snd_pcm_hw_params_set_rate_near(pcm, hwp, rate, 0);
 552-	if (err < 0) {
 553-		DALSA("couldn't set rate", err);
 554-		return 0;
 555-	}
 556-	err = snd_pcm_hw_params_set_channels_near(pcm, hwp, chans);
 557-	if (err < 0) {
 558-		DALSA("couldn't set channel count", err);
 559-		return 0;
 560-	}
 561-	err = snd_pcm_hw_params_set_periods_integer(pcm, hwp);
 562-	if (err < 0) {
 563-		DALSA("couldn't set periods to integer", err);
 564-		return 0;
 565-	}
 566-	err = snd_pcm_hw_params_set_periods_min(pcm, hwp, &min_periods, NULL);
 567-	if (err < 0) {
 568-		DALSA("couldn't set minimum periods", err);
 569-		return 0;
 570-	}
 571-	err = snd_pcm_hw_params_set_period_size_integer(pcm, hwp);
 572-	if (err < 0) {
 573-		DALSA("couldn't set period to integer", err);
 574-		return 0;
 575-	}
 576-
 577-	*round = *round * *rate / req_rate;
 578-	*round = (*round + 31) & ~31;
 579 
 580-	err = snd_pcm_hw_params_set_period_size_near(pcm, hwp, round, &dir);
 581-	if (err < 0) {
 582-		DALSA("couldn't set period size failed", err);
 583-		return 0;
 584-	}
 585-	err = snd_pcm_hw_params_set_periods_near(pcm, hwp, periods, &dir);
 586-	if (err < 0) {
 587-		DALSA("couldn't set period count", err);
 588-		return 0;
 589-	}
 590-	err = snd_pcm_hw_params(pcm, hwp);
 591+	req_rate = cfg->rate;
 592+	min = pcm_params_get_min(par, PCM_PARAM_RATE);
 593+	if (cfg->rate < min)
 594+		cfg->rate = min;
 595+	max = pcm_params_get_max(par, PCM_PARAM_RATE);
 596+	if (cfg->rate > max)
 597+		cfg->rate = max;
 598+
 599+	min = pcm_params_get_min(par, PCM_PARAM_CHANNELS);
 600+	if (cfg->channels < min)
 601+		cfg->channels = min;
 602+	max = pcm_params_get_max(par, PCM_PARAM_CHANNELS);
 603+	if (cfg->channels > max)
 604+		cfg->channels = max;
 605+
 606+	cfg->period_size = cfg->period_size * cfg->rate / req_rate;
 607+	cfg->period_size = (cfg->period_size + 31) & ~31;
 608+
 609+	min = pcm_params_get_min(par, PCM_PARAM_PERIOD_SIZE);
 610+	if (min < 2)
 611+		min = 2;
 612+	if (cfg->period_size < min)
 613+		cfg->period_size = min;
 614+	max = pcm_params_get_max(par, PCM_PARAM_PERIOD_SIZE);
 615+	if (cfg->period_size > max)
 616+		cfg->period_size = max;
 617+
 618+	min = pcm_params_get_min(par, PCM_PARAM_PERIODS);
 619+	if (cfg->period_count < min)
 620+		cfg->period_count = min;
 621+	max = pcm_params_get_max(par, PCM_PARAM_PERIODS);
 622+	if (cfg->period_count > max)
 623+		cfg->period_count = max;
 624+
 625+	cfg->start_threshold = 0;
 626+	cfg->stop_threshold = cfg->period_count * cfg->period_size;
 627+	cfg->avail_min = 1;
 628+	cfg->silence_size = 0;
 629+	cfg->silence_threshold = 0;
 630+
 631+	/* XXX: period_event=1, silence?, silence_threshold? */
 632+
 633+	err = pcm_set_config(pcm, cfg);
 634 	if (err < 0) {
 635-		DALSA("couldn't commit params", err);
 636+		DALSA("couldn't set config", pcm);
 637 		return 0;
 638 	}
 639 	return 1;
 640 }
 641 
 642 static int
 643-sio_alsa_getcap_hw(snd_pcm_t *pcm, int *rates, int *fmts, int *chans)
 644+sio_alsa_getcap_hw(struct pcm_params *par, int *rates, int *fmts, int *chans)
 645 {
 646 	int i, err;
 647-	snd_pcm_hw_params_t *hwp;
 648-
 649-	snd_pcm_hw_params_alloca(&hwp);
 650-
 651-	err = snd_pcm_hw_params_any(pcm, hwp);
 652-	if (err < 0) {
 653-		DALSA("sio_alsa_trypar: couldn't init pars", err);
 654-		return 0;
 655-	}
 656+	unsigned min, max;
 657 
 658 	*fmts = 0;
 659 	for (i = 0; i < CAP_NFMTS; i++) {
 660-		err = snd_pcm_hw_params_test_format(pcm, hwp, cap_fmts[i]);
 661+		err = pcm_params_format_test(par, cap_fmts[i]);
 662 		if (err == 0) {
 663 			*fmts |= 1 << i;
 664 		}
 665 	}
 666 	*rates = 0;
 667+	min = pcm_params_get_min(par, PCM_PARAM_RATE);
 668+	max = pcm_params_get_max(par, PCM_PARAM_RATE);
 669 	for (i = 0; i < CAP_NRATES; i++) {
 670-		err = snd_pcm_hw_params_test_rate(pcm, hwp, cap_rates[i], 0);
 671-		if (err == 0) {
 672+		if (min <= cap_rates[i] && cap_rates[i] <= max) {
 673 			*rates |= 1 << i;
 674 		}
 675 	}
 676 	*chans = 0;
 677+	min = pcm_params_get_min(par, PCM_PARAM_CHANNELS);
 678+	max = pcm_params_get_max(par, PCM_PARAM_CHANNELS);
 679 	for (i = 0; i < CAP_NCHANS; i++) {
 680-		err = snd_pcm_hw_params_test_channels(pcm, hwp, cap_chans[i]);
 681-		if (err == 0) {
 682+		if (min <= cap_chans[i] && cap_chans[i] <= max) {
 683 			*chans |= 1 << i;
 684 		}
 685 	}
 686@@ -693,13 +567,13 @@ sio_alsa_getcap(struct sio_hdl *sh, struct sio_cap *cap)
 687 	irates = orates = ifmts = ofmts = ichans = ochans = 0;
 688 
 689 	if (hdl->sio.mode & SIO_PLAY) {
 690-		if (!sio_alsa_getcap_hw(hdl->opcm,
 691+		if (!sio_alsa_getcap_hw(hdl->opar,
 692 			&orates, &ofmts, &ochans)) {
 693 			return 0;
 694 		}
 695 	}
 696 	if (hdl->sio.mode & SIO_REC) {
 697-		if (!sio_alsa_getcap_hw(hdl->ipcm,
 698+		if (!sio_alsa_getcap_hw(hdl->ipar,
 699 			&irates, &ifmts, &ichans)) {
 700 			return 0;
 701 		}
 702@@ -711,7 +585,7 @@ sio_alsa_getcap(struct sio_hdl *sh, struct sio_cap *cap)
 703 		    &cap->enc[i].sig,
 704 		    &cap->enc[i].le);
 705 		cap->enc[i].bps = SIO_BPS(cap->enc[0].bits);
 706-		cap->enc[i].msb = 1;
 707+		cap->enc[i].msb = 0;
 708 	}
 709 	for (i = 0; i < CAP_NRATES; i++) {
 710 		cap->rate[i] = cap_rates[i];
 711@@ -744,186 +618,72 @@ static int
 712 sio_alsa_setpar(struct sio_hdl *sh, struct sio_par *par)
 713 {
 714 	struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
 715-	snd_pcm_hw_params_t *ohwp, *ihwp;
 716-	snd_pcm_sw_params_t *oswp, *iswp;
 717-	snd_pcm_uframes_t iround, oround;
 718-	snd_pcm_format_t ifmt, ofmt;
 719-	unsigned int iperiods, operiods;
 720-	unsigned irate, orate;
 721-	int err;
 722-
 723-	snd_pcm_hw_params_alloca(&ohwp);
 724-	snd_pcm_sw_params_alloca(&oswp);
 725-	snd_pcm_hw_params_alloca(&ihwp);
 726-	snd_pcm_sw_params_alloca(&iswp);
 727+	struct pcm_config icfg, ocfg;
 728 
 729-	sio_alsa_enctofmt(hdl, &ifmt, par->bits, par->sig, par->le);
 730-	irate = (par->rate == ~0U) ? 48000 : par->rate;
 731+	sio_alsa_enctofmt(hdl, &icfg.format, par->bits, par->sig, par->le);
 732+	icfg.rate = (par->rate == ~0U) ? 48000 : par->rate;
 733 	if (par->appbufsz != ~0U) {
 734-		iround = (par->round != ~0U) ?
 735+		icfg.period_size = (par->round != ~0U) ?
 736 		    par->round : (par->appbufsz + 1) / 2;
 737-		iperiods = par->appbufsz / iround;
 738-		if (iperiods < 2)
 739-			iperiods = 2;
 740+		icfg.period_count = par->appbufsz / icfg.period_size;
 741+		if (icfg.period_count < 2)
 742+			icfg.period_count = 2;
 743 	} else if (par->round != ~0U) {
 744-		iround = par->round;
 745-		iperiods = 2;
 746+		icfg.period_size = par->round;
 747+		icfg.period_count = 2;
 748 	} else {
 749-		iperiods = 2;
 750-		iround = irate / 100;
 751+		icfg.period_count = 2;
 752+		icfg.period_size = icfg.rate / 100;
 753 	}
 754 
 755 	if (hdl->sio.mode & SIO_REC) {
 756 		hdl->par.rchan = par->rchan;
 757-		if (!sio_alsa_setpar_hw(hdl->ipcm, ihwp,
 758-			&ifmt, &irate, &hdl->par.rchan,
 759-			&iround, &iperiods)) {
 760+		if (!sio_alsa_setpar_hw(hdl->ipcm, hdl->ipar, &icfg)) {
 761 			hdl->sio.eof = 1;
 762 			return 0;
 763 		}
 764 	}
 765-	ofmt = ifmt;
 766-	orate = irate;
 767-	oround = iround;
 768-	operiods = iperiods;
 769+	ocfg = icfg;
 770 	if (hdl->sio.mode & SIO_PLAY) {
 771 		hdl->par.pchan = par->pchan;
 772-		if (!sio_alsa_setpar_hw(hdl->opcm, ohwp,
 773-			&ofmt, &orate, &hdl->par.pchan,
 774-			&oround, &operiods)) {
 775+		if (!sio_alsa_setpar_hw(hdl->opcm, hdl->opar, &ocfg)) {
 776 			hdl->sio.eof = 1;
 777 			return 0;
 778 		}
 779-		if (!(hdl->sio.mode & SIO_REC)) {
 780-			ifmt = ofmt;
 781-			irate = orate;
 782-			iround = oround;
 783-			iperiods = operiods;
 784-		}
 785+		if (!(hdl->sio.mode & SIO_REC))
 786+			icfg = ocfg;
 787 	}
 788 
 789 	DPRINTFN(2, "ofmt = %u, orate = %u, oround = %u, operiods = %u\n",
 790-	    ofmt, orate, (unsigned int)oround, operiods);
 791+	    ocfg.format, ocfg.rate, ocfg.period_size, ocfg.period_count);
 792 	DPRINTFN(2, "ifmt = %u, irate = %u, iround = %u, iperiods = %u\n",
 793-	    ifmt, irate, (unsigned int)iround, iperiods);
 794+	    icfg.format, icfg.rate, icfg.period_size, icfg.period_count);
 795 
 796-	if (ifmt != ofmt) {
 797+	if (icfg.format != ocfg.format) {
 798 		DPRINTF("play and rec formats differ\n");
 799 		hdl->sio.eof = 1;
 800 		return 0;
 801 	}
 802-	if (irate != orate) {
 803+	if (icfg.rate != ocfg.rate) {
 804 		DPRINTF("play and rec rates differ\n");
 805 		hdl->sio.eof = 1;
 806 		return 0;
 807 	}
 808-	if (iround != oround) {
 809+	if (icfg.period_size != ocfg.period_size) {
 810 		DPRINTF("play and rec block sizes differ\n");
 811 		hdl->sio.eof = 1;
 812 		return 0;
 813 	}
 814-	if (!sio_alsa_fmttopar(hdl, ifmt,
 815+	if (!sio_alsa_fmttopar(hdl, icfg.format,
 816 		&hdl->par.bits, &hdl->par.sig, &hdl->par.le))
 817 		return 0;
 818-	hdl->par.msb = 1;
 819+	hdl->par.msb = 0;
 820 	hdl->par.bps = SIO_BPS(hdl->par.bits);
 821-	hdl->par.rate = orate;
 822-	hdl->par.round = oround;
 823-	hdl->par.bufsz = oround * operiods;
 824+	hdl->par.rate = ocfg.rate;
 825+	hdl->par.round = ocfg.period_size;
 826+	hdl->par.bufsz = ocfg.period_size * ocfg.period_count;
 827 	hdl->par.appbufsz = hdl->par.bufsz;
 828 
 829-	/* software params */
 830-
 831-	if (hdl->sio.mode & SIO_REC) {
 832-		err = snd_pcm_sw_params_current(hdl->ipcm, iswp);
 833-		if (err < 0) {
 834-			DALSA("couldn't get current rec params", err);
 835-			hdl->sio.eof = 1;
 836-			return 0;
 837-		}
 838-		err = snd_pcm_sw_params_set_start_threshold(hdl->ipcm,
 839-		    iswp, 0);
 840-		if (err < 0) {
 841-			DALSA("couldn't set rec start threshold", err);
 842-			hdl->sio.eof = 1;
 843-			return 0;
 844-		}
 845-		err = snd_pcm_sw_params_set_stop_threshold(hdl->ipcm,
 846-		    iswp, hdl->par.bufsz);
 847-		if (err < 0) {
 848-			DALSA("couldn't set rec stop threshold", err);
 849-			hdl->sio.eof = 1;
 850-			return 0;
 851-		}
 852-		err = snd_pcm_sw_params_set_avail_min(hdl->ipcm,
 853-		    iswp, 1);
 854-		if (err < 0) {
 855-			DALSA("couldn't set rec avail min", err);
 856-			hdl->sio.eof = 1;
 857-			return 0;
 858-		}
 859-		err = snd_pcm_sw_params_set_period_event(hdl->ipcm, iswp, 1);
 860-		if (err < 0) {
 861-			DALSA("couldn't set rec period event", err);
 862-			hdl->sio.eof = 1;
 863-			return 0;
 864-		}
 865-		err = snd_pcm_sw_params(hdl->ipcm, iswp);
 866-		if (err < 0) {
 867-			DALSA("couldn't commit rec sw params", err);
 868-			hdl->sio.eof = 1;
 869-			return 0;
 870-		}
 871-	}
 872-	if (hdl->sio.mode & SIO_PLAY) {
 873-		err = snd_pcm_sw_params_current(hdl->opcm, oswp);
 874-		if (err < 0) {
 875-			DALSA("couldn't get current play params", err);
 876-			hdl->sio.eof = 1;
 877-			return 0;
 878-		}
 879-		err = snd_pcm_sw_params_set_start_threshold(hdl->opcm,
 880-		    oswp, hdl->par.bufsz - hdl->par.round);
 881-		if (err < 0) {
 882-			DALSA("couldn't set play start threshold", err);
 883-			hdl->sio.eof = 1;
 884-			return 0;
 885-		}
 886-		err = snd_pcm_sw_params_set_stop_threshold(hdl->opcm,
 887-		    oswp, hdl->par.bufsz);
 888-		if (err < 0) {
 889-			DALSA("couldn't set play stop threshold", err);
 890-			hdl->sio.eof = 1;
 891-			return 0;
 892-		}
 893-		err = snd_pcm_sw_params_set_avail_min(hdl->opcm,
 894-		    oswp, 1);
 895-		if (err < 0) {
 896-			DALSA("couldn't set play avail min", err);
 897-			hdl->sio.eof = 1;
 898-			return 0;
 899-		}
 900-		err = snd_pcm_sw_params_set_period_event(hdl->opcm, oswp, 1);
 901-		if (err < 0) {
 902-			DALSA("couldn't set play period event", err);
 903-			hdl->sio.eof = 1;
 904-			return 0;
 905-		}
 906-		err = snd_pcm_sw_params(hdl->opcm, oswp);
 907-		if (err < 0) {
 908-			DALSA("couldn't commit play sw params", err);
 909-			hdl->sio.eof = 1;
 910-			return 0;
 911-		}
 912-	}
 913-#ifdef DEBUG
 914-	if (_sndio_debug >= 2) {
 915-		if (hdl->sio.mode & SIO_REC)
 916-			snd_pcm_dump(hdl->ipcm, output);
 917-		if (hdl->sio.mode & SIO_PLAY)
 918-			snd_pcm_dump(hdl->opcm, output);
 919-	}
 920-#endif
 921 	return 1;
 922 }
 923 
 924@@ -940,7 +700,7 @@ static size_t
 925 sio_alsa_read(struct sio_hdl *sh, void *buf, size_t len)
 926 {
 927 	struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
 928-	snd_pcm_sframes_t n;
 929+	int n;
 930 	size_t todo;
 931 
 932 	if (hdl->ipartial > 0) {
 933@@ -959,7 +719,7 @@ sio_alsa_read(struct sio_hdl *sh, void *buf, size_t len)
 934 	todo = len / hdl->ibpf;
 935 	if (todo == 0)
 936 		return 0;
 937-	while ((n = snd_pcm_readi(hdl->ipcm, buf, todo)) < 0) {
 938+	while ((n = pcm_readi(hdl->ipcm, buf, todo)) < 0) {
 939 		if (n == -EINTR)
 940 			continue;
 941 		if (n == -EPIPE || n == -ESTRPIPE) {
 942@@ -967,7 +727,7 @@ sio_alsa_read(struct sio_hdl *sh, void *buf, size_t len)
 943 			return 0;
 944 		}
 945 		if (n != -EAGAIN) {
 946-			DALSA("couldn't read data", n);
 947+			DALSA("couldn't read data", hdl->ipcm);
 948 			hdl->sio.eof = 1;
 949 		}
 950 		return 0;
 951@@ -989,7 +749,7 @@ static size_t
 952 sio_alsa_write(struct sio_hdl *sh, const void *buf, size_t len)
 953 {
 954 	struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
 955-	snd_pcm_sframes_t n;
 956+	int n;
 957 	size_t todo;
 958 
 959 	if (len < hdl->obpf || hdl->opartial > 0) {
 960@@ -1007,7 +767,7 @@ sio_alsa_write(struct sio_hdl *sh, const void *buf, size_t len)
 961 	todo = len / hdl->obpf;
 962 	if (todo == 0)
 963 		return 0;
 964-	while ((n = snd_pcm_writei(hdl->opcm, buf, todo)) < 0) {
 965+	while ((n = pcm_writei(hdl->opcm, buf, todo)) < 0) {
 966 		if (n == -EINTR)
 967 			continue;
 968 		if (n == -ESTRPIPE || n == -EPIPE) {
 969@@ -1015,7 +775,7 @@ sio_alsa_write(struct sio_hdl *sh, const void *buf, size_t len)
 970 			return 0;
 971 		}
 972 		if (n != -EAGAIN) {
 973-			DALSA("couldn't write data", n);
 974+			DALSA("couldn't write data", hdl->opcm);
 975 			hdl->sio.eof = 1;
 976 		}
 977 		return 0;
 978@@ -1062,16 +822,14 @@ sio_alsa_onmove(struct sio_alsa_hdl *hdl)
 979 static int
 980 sio_alsa_nfds(struct sio_hdl *sh)
 981 {
 982-	struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
 983-
 984-	return hdl->nfds;
 985+	return 2;
 986 }
 987 
 988 static int
 989 sio_alsa_pollfd(struct sio_hdl *sh, struct pollfd *pfd, int events)
 990 {
 991 	struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
 992-	int i;
 993+	int i, nfds;
 994 
 995 	if (hdl->sio.eof)
 996 		return 0;
 997@@ -1083,100 +841,86 @@ sio_alsa_pollfd(struct sio_hdl *sh, struct pollfd *pfd, int events)
 998 		hdl->events &= ~POLLIN;
 999 	if (!hdl->sio.started)
1000 		hdl->events = 0;
1001-	memset(pfd, 0, sizeof(struct pollfd) * hdl->nfds);
1002-	hdl->onfds = hdl->infds = 0;
1003+	memset(pfd, 0, sizeof(struct pollfd) * 2);
1004+	nfds = 0;
1005 	if (hdl->events & POLLOUT) {
1006 		if (!hdl->running &&
1007-		    snd_pcm_state(hdl->opcm) == SND_PCM_STATE_RUNNING)
1008+		    pcm_state(hdl->opcm) == PCM_STATE_RUNNING)
1009 			sio_alsa_onmove(hdl);
1010-		hdl->onfds = snd_pcm_poll_descriptors(hdl->opcm,
1011-		    pfd, hdl->nfds);
1012-		if (hdl->onfds < 0) {
1013-			DALSA("couldn't poll play descriptors",
1014-			    hdl->onfds);
1015-			hdl->sio.eof = 1;
1016-			return 0;
1017-		}
1018+
1019+		pfd[0].fd = pcm_get_poll_fd(hdl->opcm);
1020+		pfd[0].events = POLLOUT;
1021+		nfds++;
1022 	}
1023 	if (hdl->events & POLLIN) {
1024 		if (!hdl->running &&
1025-		    snd_pcm_state(hdl->ipcm) == SND_PCM_STATE_RUNNING)
1026+		    pcm_state(hdl->ipcm) == PCM_STATE_RUNNING)
1027 			sio_alsa_onmove(hdl);
1028-		hdl->infds = snd_pcm_poll_descriptors(hdl->ipcm,
1029-		    pfd + hdl->onfds, hdl->nfds - hdl->onfds);
1030-		if (hdl->infds < 0) {
1031-			DALSA("couldn't poll rec descriptors",
1032-			    hdl->infds);
1033-			hdl->sio.eof = 1;
1034-			return 0;
1035-		}
1036+
1037+		pfd[nfds].fd = pcm_get_poll_fd(hdl->ipcm);
1038+		pfd[nfds].events = POLLIN;
1039+		nfds++;
1040 	}
1041-	DPRINTFN(4, "sio_alsa_pollfd: events = %x, nfds = %d + %d\n",
1042-	    events, hdl->onfds, hdl->infds);
1043+	DPRINTFN(4, "sio_alsa_pollfd: events = %x, nfds = %d\n",
1044+	    events, nfds);
1045 
1046-	for (i = 0; i < hdl->onfds + hdl->infds; i++) {
1047+	for (i = 0; i < nfds; i++) {
1048 		DPRINTFN(4, "sio_alsa_pollfd: pfds[%d].events = %x\n",
1049 		    i, pfd[i].events);
1050 	}
1051-	return hdl->onfds + hdl->infds;
1052+	return nfds;
1053 }
1054 
1055 int
1056 sio_alsa_revents(struct sio_hdl *sh, struct pollfd *pfd)
1057 {
1058 	struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
1059-	snd_pcm_sframes_t iused, oavail, oused;
1060-	snd_pcm_state_t istate, ostate;
1061-	unsigned short revents, r;
1062-	int nfds, err, i;
1063+	struct timespec ts;
1064+	unsigned iused, oavail, oused;
1065+	int istate, ostate;
1066+	unsigned short revents;
1067+	int nfds, i;
1068 
1069 	if (hdl->sio.eof)
1070 		return POLLHUP;
1071 
1072-	for (i = 0; i < hdl->onfds + hdl->infds; i++) {
1073+	nfds = 0;
1074+	if (hdl->events & POLLOUT)
1075+		nfds++;
1076+	if (hdl->events & POLLIN)
1077+		nfds++;
1078+
1079+	for (i = 0; i < nfds; i++) {
1080 		DPRINTFN(4, "sio_alsa_revents: pfds[%d].revents = %x\n",
1081 		    i, pfd[i].revents);
1082 	}
1083 	revents = nfds = 0;
1084 	if (hdl->events & POLLOUT) {
1085-		err = snd_pcm_poll_descriptors_revents(hdl->opcm,
1086-		    pfd, hdl->onfds, &r);
1087-		if (err < 0) {
1088-			DALSA("couldn't get play events", err);
1089-			hdl->sio.eof = 1;
1090-			return POLLHUP;
1091-		}
1092-		revents |= r;
1093-		nfds += hdl->onfds;
1094+		revents |= pfd[0].revents;
1095+		++nfds;
1096 	}
1097 	if (hdl->events & POLLIN) {
1098-		err = snd_pcm_poll_descriptors_revents(hdl->ipcm,
1099-		    pfd + nfds, hdl->infds, &r);
1100-		if (err < 0) {
1101-			DALSA("couldn't get rec events", err);
1102-			hdl->sio.eof = 1;
1103-			return POLLHUP;
1104-		}
1105-		revents |= r;
1106-		nfds += hdl->infds;
1107+		revents |= pfd[nfds].revents;
1108+		++nfds;
1109 	}
1110 	if (hdl->sio.mode & SIO_PLAY) {
1111-		ostate = snd_pcm_state(hdl->opcm);
1112-		if (ostate == SND_PCM_STATE_XRUN) {
1113+		ostate = pcm_state(hdl->opcm);
1114+		if (ostate == PCM_STATE_XRUN) {
1115 			if (!sio_alsa_xrun(hdl))
1116 				return POLLHUP;
1117 			return 0;
1118 		}
1119-		if (ostate == SND_PCM_STATE_RUNNING ||
1120-		    ostate == SND_PCM_STATE_PREPARED) {
1121-			oavail = snd_pcm_avail_update(hdl->opcm);
1122-			if (oavail < 0) {
1123+		if (ostate == PCM_STATE_RUNNING ||
1124+		    ostate == PCM_STATE_PREPARED) {
1125+			if (pcm_get_htimestamp(hdl->opcm, &oavail, &ts) != 0) {
1126+				/*
1127 				if (oavail == -EPIPE || oavail == -ESTRPIPE) {
1128 					if (!sio_alsa_xrun(hdl))
1129 						return POLLHUP;
1130 					return 0;
1131 				}
1132-				DALSA("couldn't get play buffer ptr", oavail);
1133+				*/
1134+				DPRINTF("couldn't get play buffer ptr\n");
1135 				hdl->sio.eof = 1;
1136 				return POLLHUP;
1137 			}
1138@@ -1186,22 +930,23 @@ sio_alsa_revents(struct sio_hdl *sh, struct pollfd *pfd)
1139 		}
1140 	}
1141 	if (hdl->sio.mode & SIO_REC) {
1142-		istate = snd_pcm_state(hdl->ipcm);
1143-		if (istate == SND_PCM_STATE_XRUN) {
1144+		istate = pcm_state(hdl->ipcm);
1145+		if (istate == PCM_STATE_XRUN) {
1146 			if (!sio_alsa_xrun(hdl))
1147 				return POLLHUP;
1148 			return 0;
1149 		}
1150-		if (istate == SND_PCM_STATE_RUNNING ||
1151-		    istate == SND_PCM_STATE_PREPARED) {
1152-			iused = snd_pcm_avail_update(hdl->ipcm);
1153-			if (iused < 0) {
1154+		if (istate == PCM_STATE_RUNNING ||
1155+		    istate == PCM_STATE_PREPARED) {
1156+			if (pcm_get_htimestamp(hdl->ipcm, &iused, &ts) != 0) {
1157+				/*
1158 				if (iused == -EPIPE || iused == -ESTRPIPE) {
1159 					if (!sio_alsa_xrun(hdl))
1160 						return POLLHUP;
1161 					return 0;
1162 				}
1163-				DALSA("couldn't get rec buffer ptr", iused);
1164+				*/
1165+				DPRINTF("couldn't get rec buffer ptr\n");
1166 				hdl->sio.eof = 1;
1167 				return POLLHUP;
1168 			}
1169-- 
11702.37.3
1171