$OpenBSD: patch-src_snd_c,v 1.2 2010/04/26 01:47:15 jakemsr Exp $
--- src/snd.c.orig	Sat Apr 17 10:24:11 2004
+++ src/snd.c	Sun Apr 18 16:52:21 2010
@@ -36,8 +36,7 @@
 #include <fcntl.h>
 #include <time.h>
 
-#include <sys/soundcard.h>
-#include <sys/ioctl.h>
+#include <sndio.h>
 
 #include "snd.h"
 #include "misc.h"
@@ -55,6 +54,7 @@
 static snd_config_t config;
 static snd_config_t newconfig;
 
+static struct sio_hdl *hdl = NULL;
 static gint snd_fd = -1;
 static gint snd_dir = 0;
 
@@ -133,18 +133,17 @@ static void dprintf(const char *fmt, ...)
 
 /* ---------------------------------------------------------------------- */
 
-static gint opensnd(gint direction)
+static struct sio_hdl * opensnd(gint direction)
 {
 #ifdef SND_DEBUG
-	audio_buf_info info;
 	gchar *str;
 #endif
-	guint sndparam, wanted;
-	gint fd;
+	struct sio_hdl *h;
+	struct sio_par par, gpar;
 
 	if (!config.device) {
 		snderr("opensnd: device not set");
-		return -1;
+		return NULL;
 	}
 
 #ifdef SND_DEBUG
@@ -165,18 +164,16 @@ static gint opensnd(gint direction)
 	dprintf("Opening %s for %s...\n", config.device, str);
 #endif
 
-	/* non-blocking open */
-	if ((fd = open(config.device, direction | O_NONBLOCK)) < 0) {
-		snderr("opensnd: open: %s: %m", config.device);
-		return -1;
+        if (!strncmp(config.device, "", 1) || 
+	    !strncmp(config.device, "default", 8))
+		h = sio_open(NULL, direction, 0);
+	else
+		h = sio_open(config.device, direction, 0);
+	if (!h) {
+		snderr("opensnd: open: %s", config.device);
+		return NULL;
 	}
 
-	/* make it block again - (SNDCTL_DSP_NONBLOCK ???) */
-	if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK) < 0) {
-		snderr("opensnd: ioctl: SNDCTL_DSP_NONBLOCK: %m");
-		goto error;
-	}
-
 #ifdef SND_DEBUG
 	if (config.flags & SND_FLAG_8BIT)
 		str = "8 bit unsigned";
@@ -186,20 +183,15 @@ static gint opensnd(gint direction)
 	dprintf("Setting sample format (%s)...\n", str);
 #endif
 
-	if (config.flags & SND_FLAG_8BIT)
-		wanted = AFMT_U8;	/* 8 bit unsigned */
-	else
-		wanted = AFMT_S16_NE;	/* 16 bit signed, native byteorder */
+	sio_initpar(&par);
 
-	sndparam = wanted;
-	if (ioctl(fd, SNDCTL_DSP_SETFMT, &sndparam) < 0) {
-		snderr("opensnd: ioctl: SNDCTL_DSP_SETFMT: %m");
-		goto error;
+	if (config.flags & SND_FLAG_8BIT) {
+		par.bits = 8;
+		par.sig = 0;
+	} else {
+		par.bits = 16;
+		par.sig = 1;
 	}
-	if (sndparam != wanted) {
-		snderr("opensnd: Requested sample format not supported");
-		goto error;
-	}
 
 #ifdef SND_DEBUG
 	dprintf("Setting %s audio...\n",
@@ -207,85 +199,50 @@ static gint opensnd(gint direction)
 #endif
 
 	if (config.flags & SND_FLAG_STEREO)
-		wanted = 1;		/* stereo */
+		par.pchan = par.rchan = 2;
 	else
-		wanted = 0;		/* mono */
+		par.pchan = par.rchan = 1;
 
-	sndparam = wanted;
-	if (ioctl(fd, SNDCTL_DSP_STEREO, &sndparam) < 0) {
-		snderr("opensnd: ioctl: SNDCTL_DSP_STEREO: %m");
-		goto error;
-	}
-	if (sndparam != wanted) {
-		snderr("opensnd: Cannot set %s audio",
-		       (config.flags & SND_FLAG_STEREO) ? "stereo" : "mono");
-		goto error;
-	}
-
 #ifdef SND_DEBUG
 	dprintf("Setting samplerate to %u...\n", config.samplerate);
 #endif
 
-	sndparam = config.samplerate;
-	if (ioctl(fd, SNDCTL_DSP_SPEED, &sndparam) < 0) {
-		snderr("opensnd: ioctl: SNDCTL_DSP_SPEED: %m");
-		goto error;
-	}
-	if (sndparam != config.samplerate) {
-		g_warning("Sampling rate is %u, requested %u\n",
-			  sndparam,
-			  config.samplerate);
-	}
-	config.samplerate = sndparam;
+	par.rate = config.samplerate;
 
 	/* Request a buffer size of 512 samples */
-	if (config.flags & SND_FLAG_8BIT)
-		sndparam = 0x00000009;
-	else
-		sndparam = 0x0000000A;
+	par.round = 512;
+	par.appbufsz = par.round * 4;
 
-	if (config.flags & SND_FLAG_STEREO)
-		sndparam += 1;
-
-	/* Unlimited amount of buffers for RX, four for TX */
-	if (direction == O_RDONLY)
-		sndparam |= 0x7FFF0000;
-	else
-		sndparam |= 0x00040000;
-
 #ifdef SND_DEBUG
-	dprintf("Setting fragment size (param = 0x%08X)...\n", sndparam);
+	dprintf("-- \n");
 #endif
 
-	if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &sndparam) < 0) {
-		snderr("opensnd: ioctl: SNDCTL_DSP_SETFRAGMENT: %m");
+	if (!sio_setpar(h, &par) || !sio_getpar(h, &gpar) ||
+	    gpar.bits != par.bits || gpar.sig != par.sig) {
+		snderr("sndopen: could not set parameters as desired");
 		goto error;
 	}
 
 #ifdef SND_DEBUG
-	if (direction == O_RDONLY) {
-		if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) < 0) {
-			dprintf("ioctl: SNDCTL_DSP_GETISPACE: %m");
-		}
-	} else {
-		if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) < 0) {
-			dprintf("ioctl: SNDCTL_DSP_GETOSPACE: %m");
-		}
-	}
-
-	dprintf("Audio buffer size: %d bytes, number of buffers: %d\n",
-		info.fragsize, info.fragstotal);
+	dprintf("samplerate: %u / want %u\n",
+	    gpar.rate, config.samplerate);
+	dprintf("channels: play %u / record %u / want %u\n",
+	    gpar.pchan, gpar.rchan,
+	    (config.flags & SND_FLAG_STEREO) ? 2 : 1);
 #endif
 
-#ifdef SND_DEBUG
-	dprintf("-- \n");
-#endif
+	config.samplerate = gpar.rate;
 
-	return fd;
+	if (!sio_start(h)) {
+		snderr("sndopen: could not start sndio");
+		goto error;
+	}
 
+	return h;
+
 error:
-	close(fd);
-	return -1;
+	sio_close(h);
+	return NULL;
 }
 
 /* ---------------------------------------------------------------------- */
@@ -307,11 +264,9 @@ gint sound_open_for_write(gint rate)
 	if (config.flags & SND_FLAG_TESTMODE_MASK)
 		snd_fd = 1;
 	else if (!(config.flags & SND_FLAG_FULLDUP))
-		snd_fd = opensnd(O_WRONLY);
-	else if (snd_fd < 0)
-		snd_fd = opensnd(O_RDWR);
+		hdl = opensnd(SIO_PLAY);
 
-	if (snd_fd < 0)
+	if (hdl == NULL && snd_fd != 1)
 		return -1;
 
 	snd_dir = O_WRONLY;
@@ -323,14 +278,14 @@ gint sound_open_for_write(gint rate)
 			src_delete(tx_src_state);
 			tx_src_state = NULL;
 		}
-		return snd_fd;
+		return 0;
 	}
 
 	ratio = real_rate / rate;
 
 	if (tx_src_state && tx_src_data && tx_src_data->src_ratio == ratio) {
 		src_reset(tx_src_state);
-		return snd_fd;
+		return 0;
 	}
 
 #if SND_DEBUG
@@ -354,7 +309,7 @@ gint sound_open_for_write(gint rate)
 
 	tx_src_data->src_ratio = ratio;
 
-	return snd_fd;
+	return 0;
 }
 
 gint sound_open_for_read(gint rate)
@@ -374,11 +329,9 @@ gint sound_open_for_read(gint rate)
 	if (config.flags & SND_FLAG_TESTMODE_MASK)
 		snd_fd = 0;
 	else if (!(config.flags & SND_FLAG_FULLDUP))
-		snd_fd = opensnd(O_RDONLY);
-	else if (snd_fd < 0)
-		snd_fd = opensnd(O_RDWR);
+		hdl = opensnd(SIO_REC);
 
-	if (snd_fd < 0)
+	if (hdl == NULL && snd_fd != 0)
 		return -1;
 
 	snd_dir = O_RDONLY;
@@ -390,14 +343,14 @@ gint sound_open_for_read(gint rate)
 			src_delete(rx_src_state);
 			rx_src_state = NULL;
 		}
-		return snd_fd;
+		return 0;
 	}
 
 	ratio = rate / real_rate;
 
 	if (rx_src_state && rx_src_data && rx_src_data->src_ratio == ratio) {
 		src_reset(rx_src_state);
-		return snd_fd;
+		return 0;
 	}
 
 #if SND_DEBUG
@@ -421,7 +374,7 @@ gint sound_open_for_read(gint rate)
 
 	rx_src_data->src_ratio = ratio;
 
-	return snd_fd;
+	return 0;
 }
 
 void sound_close(void)
@@ -451,13 +404,7 @@ void sound_close(void)
 	}
 #endif
 
-	/* never close stdin/out/err */
-	if (snd_fd > 2) {
-		if (ioctl(snd_fd, SNDCTL_DSP_SYNC, 0) < 0)
-			snderr("sound_close: ioctl: SNDCTL_DSP_SYNC: %m");
-		close(snd_fd);
-		snd_fd = -1;
-	}
+	sio_close(hdl);
 }
 
 char *sound_error(void)
@@ -477,8 +424,8 @@ gint sound_write(gfloat *buf, gint cnt)
 	if ((config.flags & SND_FLAG_TESTMODE_MASK) == SND_FLAG_TESTMODE_RX)
 		return cnt;
 
-	if (snd_fd < 0) {
-		snderr("sound_write: fd < 0");
+	if (hdl == NULL) {
+		snderr("sound_write: hdl == NULL");
 		return -1;
 	}
 
@@ -539,7 +486,7 @@ static gint write_samples(gfloat *buf, gint count)
 	if (config.flags & SND_FLAG_STEREO)
 		count *= 2;
 
-	if ((i = write(snd_fd, p, count)) < 0)
+	if ((i = sio_write(hdl, p, count)) < 0)
 		snderr("write_samples: write: %m");
 
 	return i;
@@ -573,8 +520,8 @@ gint sound_read(gfloat **buffer, gint *count)
 		return 0;
 	}
 
-	if (snd_fd < 0) {
-		snderr("sound_read: fd < 0");
+	if (hdl == NULL) {
+		snderr("sound_read: hdl == NULL");
 		return -1;
 	}
 
@@ -625,7 +572,7 @@ static gint read_samples(gfloat *buf, gint count)
 	if (config.flags & SND_FLAG_8BIT) {
 		count *= sizeof(guint8);
 
-		if ((len = read(snd_fd, snd_b_buffer, count)) < 0)
+		if ((len = sio_read(hdl, snd_b_buffer, count)) < 0)
 			goto error;
 
 		len /= sizeof(guint8);
@@ -641,7 +588,7 @@ static gint read_samples(gfloat *buf, gint count)
 	} else {
 		count *= sizeof(gint16);
 
-		if ((len = read(snd_fd, snd_w_buffer, count)) < 0)
+		if ((len = sio_read(hdl, snd_w_buffer, count)) < 0)
 			goto error;
 
 		len /= sizeof(gint16);
