View | Details | Raw Unified | Return to bug 214210 | Differences between
and this patch

Collapse All | Expand All

(-)b/audio/sndio/Makefile (-2 / +1 lines)
Lines 2-9 Link Here
2
# $FreeBSD$
2
# $FreeBSD$
3
3
4
PORTNAME=	sndio
4
PORTNAME=	sndio
5
PORTVERSION=	1.1.0
5
PORTVERSION=	1.2.0
6
PORTREVISION=	1
7
CATEGORIES=	audio
6
CATEGORIES=	audio
8
MASTER_SITES=	http://www.sndio.org/
7
MASTER_SITES=	http://www.sndio.org/
9
8
(-)b/audio/sndio/distinfo (-3 / +3 lines)
Lines 1-3 Link Here
1
TIMESTAMP = 1465315037
1
TIMESTAMP = 1478437502
2
SHA256 (sndio-1.1.0.tar.gz) = fcd7f845ff70f38c2898d737450b8aa3e1bb0afb9d147e8429ef22c0b2c2db57
2
SHA256 (sndio-1.2.0.tar.gz) = b9808e189481904a4404b0c1715ad0c4b301e72abca8e49653bb526ff4e16cdc
3
SIZE (sndio-1.1.0.tar.gz) = 121018
3
SIZE (sndio-1.2.0.tar.gz) = 123703
(-)a/audio/sndio/files/patch-configure (-61 lines)
Removed Link Here
1
--- configure.orig	2015-12-15 05:28:04 UTC
2
+++ configure
3
@@ -32,6 +32,7 @@ prefix=/usr/local			# where to install s
4
 so="libsndio.so.\${MAJ}.\${MIN}"	# shared libs to build
5
 alsa=no					# do we want alsa support ?
6
 sun=no					# do we want sun support ?
7
+oss=no					# do we want oss support ?
8
 rmidi=no				# do we want support for raw char dev ?
9
 precision=16				# aucat/sndiod arithmetic precision
10
 user=_sndio				# non-privileged user for sndio daemon
11
@@ -71,6 +72,15 @@ case `uname` in
12
 		defs='-DHAVE_ARC4RANDOM -DHAVE_ISSETUGID \\\
13
 		-DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRTONUM'
14
 		;;
15
+	FreeBSD)
16
+		user=_sndio
17
+		so="$so libsndio.so"
18
+		defs='-DHAVE_ARC4RANDOM -DHAVE_ISSETUGID \\\
19
+		-DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRTONUM \\\
20
+		-DDEFAULT_DEV=\\"fallback\\"'
21
+		oss=yes
22
+		mandir=${prefix}/man
23
+		;;
24
 esac
25
 
26
 # shell word separator (none)
27
@@ -106,6 +116,12 @@ for i; do
28
 	--disable-alsa)
29
 		alsa=no
30
 		shift;;
31
+	--enable-oss)
32
+		oss=yes
33
+		shift;;
34
+	--disable-oss)
35
+		oss=no
36
+		shift;;
37
 	--enable-sun)
38
 		sun=yes
39
 		shift;;
40
@@ -162,6 +178,13 @@ if [ $alsa = yes ]; then
41
 fi
42
 
43
 #
44
+# if using OSS, add corresponding parameters
45
+#
46
+if [ $oss = yes ]; then
47
+	defs="$defs -DUSE_OSS"
48
+fi
49
+
50
+#
51
 # if using Sun API, add corresponding parameters
52
 #
53
 if [ $sun = yes ]; then
54
@@ -215,6 +238,7 @@ user..................... $user
55
 libbsd................... $libbsd
56
 precision................ $precision
57
 alsa..................... $alsa
58
+oss...................... $oss
59
 sun...................... $sun
60
 rmidi.................... $rmidi
61
 
(-)a/audio/sndio/files/patch-libsndio_Makefile.in (-17 lines)
Removed Link Here
1
--- libsndio/Makefile.in.orig	2015-12-30 11:54:40 UTC
2
+++ libsndio/Makefile.in
3
@@ -99,7 +99,7 @@ clean:
4
 #
5
 OBJS = debug.o aucat.o \
6
 mio.o mio_rmidi.o mio_alsa.o mio_aucat.o \
7
-sio.o sio_alsa.o sio_aucat.o sio_sun.o \
8
+sio.o sio_alsa.o sio_aucat.o sio_oss.o sio_sun.o \
9
 issetugid.o strlcat.o strlcpy.o strtonum.o
10
 
11
 .c.o:
12
@@ -140,3 +140,5 @@ sio_aucat.o:	sio_aucat.c aucat.h amsg.h 
13
 		../bsd-compat/bsd-compat.h
14
 sio_sun.o:	sio_sun.c debug.h sio_priv.h sndio.h \
15
 		../bsd-compat/bsd-compat.h
16
+sio_oss.o:	sio_oss.c debug.h sio_priv.h sndio.h \
17
+		../bsd-compat/bsd-compat.h
(-)a/audio/sndio/files/patch-libsndio_sio.c (-28 lines)
Removed Link Here
1
--- libsndio/sio.c.orig	2016-01-08 20:51:12 UTC
2
+++ libsndio/sio.c
3
@@ -64,17 +64,25 @@ sio_open(const char *str, unsigned int m
4
 			return hdl;
5
 #if defined(USE_SUN)
6
 		return _sio_sun_open("rsnd/0", mode, nbio);
7
+#elif defined(USE_OSS)
8
+		return _sio_oss_open("fallback", mode, nbio);
9
 #elif defined(USE_ALSA)
10
 		return _sio_alsa_open("rsnd/0", mode, nbio);
11
 #else
12
 		return NULL;
13
 #endif
14
 	}
15
+#if defined(USE_OSS)
16
+	if (strcmp(str, "fallback") == 0)
17
+		return _sio_oss_open(str, mode, nbio);
18
+#endif
19
 	if (_sndio_parsetype(str, "snd"))
20
 		return _sio_aucat_open(str, mode, nbio);
21
 	if (_sndio_parsetype(str, "rsnd"))
22
 #if defined(USE_SUN)
23
 		return _sio_sun_open(str, mode, nbio);
24
+#elif defined(USE_OSS)
25
+		return _sio_oss_open(str, mode, nbio);
26
 #elif defined(USE_ALSA)
27
 		return _sio_alsa_open(str, mode, nbio);
28
 #else
(-)a/audio/sndio/files/patch-libsndio_sio__oss.c (-841 lines)
Removed Link Here
1
--- libsndio/sio_oss.c.orig	2016-08-20 02:30:22 UTC
2
+++ libsndio/sio_oss.c
3
@@ -0,0 +1,838 @@
4
+/*	$OpenBSD$	*/
5
+/*
6
+ * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
7
+ * Copyright (c) 2016 Tobias Kortkamp <t@tobik.me>
8
+ *
9
+ * Permission to use, copy, modify, and distribute this software for any
10
+ * purpose with or without fee is hereby granted, provided that the above
11
+ * copyright notice and this permission notice appear in all copies.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
+ */
21
+
22
+#ifdef USE_OSS
23
+#include <sys/types.h>
24
+#include <sys/ioctl.h>
25
+#include <sys/param.h>
26
+#include <sys/soundcard.h>
27
+#include <sys/stat.h>
28
+
29
+#include <errno.h>
30
+#include <fcntl.h>
31
+#include <limits.h>
32
+#include <poll.h>
33
+#include <stdio.h>
34
+#include <stdlib.h>
35
+#include <string.h>
36
+#include <unistd.h>
37
+
38
+#include "debug.h"
39
+#include "sio_priv.h"
40
+#include "bsd-compat.h"
41
+
42
+#define DEVPATH_PREFIX	"/dev/dsp"
43
+#define DEVPATH_MAX 	(1 +		\
44
+	sizeof(DEVPATH_PREFIX) - 1 +	\
45
+	sizeof(int) * 3)
46
+
47
+#define AUDIO_INITPAR(p)						\
48
+	(void)memset((void *)(p), 0xff, sizeof(struct audio_swpar))
49
+
50
+/*
51
+ * argument to AUDIO_SETPAR and AUDIO_GETPAR ioctls
52
+ */
53
+struct audio_swpar {
54
+	unsigned int sig;		/* if 1, encoding is signed */
55
+	unsigned int le;		/* if 1, encoding is little-endian */
56
+	unsigned int bits;		/* bits per sample */
57
+	unsigned int bps;		/* bytes per sample */
58
+	unsigned int msb;		/* if 1, bits are msb-aligned */
59
+	unsigned int rate;		/* common play & rec sample rate */
60
+	unsigned int pchan;		/* play channels */
61
+	unsigned int rchan;		/* rec channels */
62
+	unsigned int nblks;		/* number of blocks in play buffer */
63
+	unsigned int round;		/* common frames per block */
64
+	unsigned int _spare[6];
65
+};
66
+
67
+struct sio_oss_hdl {
68
+	struct sio_hdl sio;
69
+	int fd;
70
+	unsigned int ibpf, obpf;	/* bytes per frame */
71
+	unsigned int isamples;
72
+	unsigned int osamples;
73
+	int idelta, odelta;		/* position reported to client */
74
+
75
+	char *devstr;
76
+
77
+	/* OSS doesn't have an API to ask for device parameters
78
+	 * without setting them, so we keep track of them ourselves.
79
+	 */
80
+	struct audio_swpar swpar;
81
+};
82
+
83
+static void sio_oss_close(struct sio_hdl *);
84
+static int sio_oss_start(struct sio_hdl *);
85
+static int sio_oss_stop(struct sio_hdl *);
86
+static int sio_oss_setpar(struct sio_hdl *, struct sio_par *);
87
+static int sio_oss_getpar(struct sio_hdl *, struct sio_par *);
88
+static int sio_oss_getcap(struct sio_hdl *, struct sio_cap *);
89
+static size_t sio_oss_read(struct sio_hdl *, void *, size_t);
90
+static size_t sio_oss_write(struct sio_hdl *, const void *, size_t);
91
+static int sio_oss_nfds(struct sio_hdl *);
92
+static int sio_oss_pollfd(struct sio_hdl *, struct pollfd *, int);
93
+static int sio_oss_revents(struct sio_hdl *, struct pollfd *);
94
+
95
+static void sio_oss_fmt_to_swpar(int, struct audio_swpar *);
96
+static int sio_oss_audio_getpar(struct sio_oss_hdl *, struct audio_swpar *);
97
+static int sio_oss_audio_setpar(struct sio_oss_hdl *, struct audio_swpar *);
98
+static int sio_oss_reopen(struct sio_oss_hdl *);
99
+
100
+static struct sio_ops sio_oss_ops = {
101
+	sio_oss_close,
102
+	sio_oss_setpar,
103
+	sio_oss_getpar,
104
+	sio_oss_getcap,
105
+	sio_oss_write,
106
+	sio_oss_read,
107
+	sio_oss_start,
108
+	sio_oss_stop,
109
+	sio_oss_nfds,
110
+	sio_oss_pollfd,
111
+	sio_oss_revents,
112
+	NULL, /* setvol */
113
+	NULL, /* getvol */
114
+};
115
+
116
+static int
117
+sio_oss_adjpar(struct sio_oss_hdl *hdl, struct audio_swpar *ap)
118
+{
119
+	if (hdl->sio.eof)
120
+		return 0;
121
+	if (sio_oss_audio_setpar(hdl, ap)) {
122
+		DPERROR("AUDIO_SETPAR");
123
+		hdl->sio.eof = 1;
124
+		return 0;
125
+	}
126
+	if (sio_oss_audio_getpar(hdl, ap)) {
127
+		DPERROR("AUDIO_GETPAR");
128
+		hdl->sio.eof = 1;
129
+		return 0;
130
+	}
131
+	return 1;
132
+}
133
+
134
+/*
135
+ * try to set the device to the given parameters and check that the
136
+ * device can use them; return 1 on success, 0 on failure or error
137
+ */
138
+static int
139
+sio_oss_testpar(struct sio_oss_hdl *hdl, struct sio_enc *enc,
140
+    unsigned int pchan, unsigned int rchan, unsigned int rate)
141
+{
142
+	struct audio_swpar ap;
143
+
144
+	AUDIO_INITPAR(&ap);
145
+	if (enc != NULL) {
146
+		ap.sig = enc->sig;
147
+		ap.bits = enc->bits;
148
+		ap.bps = enc->bps;
149
+		if (ap.bps > 1)
150
+			ap.le = enc->le;
151
+		if (ap.bps * 8 > ap.bits)
152
+			ap.msb = enc->msb;
153
+	}
154
+	if (rate)
155
+		ap.rate = rate;
156
+	if (pchan && (hdl->sio.mode & SIO_PLAY))
157
+		ap.pchan = pchan;
158
+	if (rchan && (hdl->sio.mode & SIO_REC))
159
+		ap.rchan = rchan;
160
+	if (!sio_oss_adjpar(hdl, &ap))
161
+		return 0;
162
+	if (pchan && ap.pchan != pchan)
163
+		return 0;
164
+	if (rchan && ap.rchan != rchan)
165
+		return 0;
166
+	if (rate && ap.rate != rate)
167
+		return 0;
168
+	if (enc) {
169
+		if (ap.sig != enc->sig)
170
+			return 0;
171
+		if (ap.bits != enc->bits)
172
+			return 0;
173
+		if (ap.bps != enc->bps)
174
+			return 0;
175
+		if (ap.bps > 1 && ap.le != enc->le)
176
+			return 0;
177
+		if (ap.bits < ap.bps * 8 && ap.msb != enc->msb)
178
+			return 0;
179
+	}
180
+	return 1;
181
+}
182
+
183
+/*
184
+ * guess device capabilities
185
+ */
186
+static int
187
+sio_oss_getcap(struct sio_hdl *sh, struct sio_cap *cap)
188
+{
189
+	static unsigned int chans[] = {
190
+		1, 2, 4, 6, 8, 10, 12
191
+	};
192
+	static unsigned int rates[] = {
193
+		8000, 11025, 12000, 16000, 22050, 24000,
194
+		32000, 44100, 48000, 64000, 88200, 96000
195
+	};
196
+	static unsigned int encs[] = {
197
+		8, 16, 24, 32
198
+	};
199
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
200
+	struct audio_swpar savepar, ap;
201
+	unsigned int nconf = 0;
202
+	unsigned int enc_map = 0, rchan_map = 0, pchan_map = 0, rate_map;
203
+	unsigned int i, j, conf;
204
+
205
+	if (sio_oss_audio_getpar(hdl, &savepar)) {
206
+		DPERROR("AUDIO_GETPAR");
207
+		hdl->sio.eof = 1;
208
+		return 0;
209
+	}
210
+
211
+	/*
212
+	 * get a subset of supported encodings
213
+	 */
214
+	for (i = 0; i < sizeof(encs) / sizeof(encs[0]); i++) {
215
+		AUDIO_INITPAR(&ap);
216
+		ap.bits = encs[i];
217
+		ap.sig = (ap.bits > 8) ? 1 : 0;
218
+		if (!sio_oss_adjpar(hdl, &ap))
219
+			return 0;
220
+		if (ap.bits == encs[i]) {
221
+			cap->enc[i].sig = ap.sig;
222
+			cap->enc[i].bits = ap.bits;
223
+			cap->enc[i].le = ap.le;
224
+			cap->enc[i].bps = ap.bps;
225
+			cap->enc[i].msb = ap.msb;
226
+			enc_map |= 1 << i;
227
+		}
228
+	}
229
+
230
+	/*
231
+	 * fill channels
232
+	 *
233
+	 * for now we're lucky: all kernel devices assume that the
234
+	 * number of channels and the encoding are independent so we can
235
+	 * use the current encoding and try various channels.
236
+	 */
237
+	if (hdl->sio.mode & SIO_PLAY) {
238
+		for (i = 0; i < sizeof(chans) / sizeof(chans[0]); i++) {
239
+			AUDIO_INITPAR(&ap);
240
+			ap.pchan = chans[i];
241
+			if (!sio_oss_adjpar(hdl, &ap))
242
+				return 0;
243
+			if (ap.pchan == chans[i]) {
244
+				cap->pchan[i] = chans[i];
245
+				pchan_map |= (1 << i);
246
+			}
247
+		}
248
+	}
249
+	if (hdl->sio.mode & SIO_REC) {
250
+		for (i = 0; i < sizeof(chans) / sizeof(chans[0]); i++) {
251
+			AUDIO_INITPAR(&ap);
252
+			ap.pchan = chans[i];
253
+			if (!sio_oss_adjpar(hdl, &ap))
254
+				return 0;
255
+			if (ap.rchan == chans[i]) {
256
+				cap->rchan[i] = chans[i];
257
+				rchan_map |= (1 << i);
258
+			}
259
+		}
260
+	}
261
+
262
+	/*
263
+	 * fill rates
264
+	 *
265
+	 * rates are not independent from other parameters (eg. on
266
+	 * uaudio devices), so certain rates may not be allowed with
267
+	 * certain encodings. We have to check rates for all encodings
268
+	 */
269
+	for (j = 0; j < sizeof(encs) / sizeof(encs[0]); j++) {
270
+		rate_map = 0;
271
+		if ((enc_map & (1 << j)) == 0)
272
+			continue;
273
+		for (i = 0; i < sizeof(rates) / sizeof(rates[0]); i++) {
274
+			if (sio_oss_testpar(hdl,
275
+				&cap->enc[j], 0, 0, rates[i])) {
276
+				cap->rate[i] = rates[i];
277
+				rate_map |= (1 << i);
278
+			}
279
+		}
280
+		for (conf = 0; conf < nconf; conf++) {
281
+			if (cap->confs[conf].rate == rate_map) {
282
+				cap->confs[conf].enc |= (1 << j);
283
+				break;
284
+			}
285
+		}
286
+		if (conf == nconf) {
287
+			if (nconf == SIO_NCONF)
288
+				break;
289
+			cap->confs[nconf].enc = (1 << j);
290
+			cap->confs[nconf].pchan = pchan_map;
291
+			cap->confs[nconf].rchan = rchan_map;
292
+			cap->confs[nconf].rate = rate_map;
293
+			nconf++;
294
+		}
295
+	}
296
+	cap->nconf = nconf;
297
+
298
+	if (sio_oss_audio_setpar(hdl, &savepar)) {
299
+		DPERROR("AUDIO_SETPAR");
300
+		hdl->sio.eof = 1;
301
+		return 0;
302
+	}
303
+	return 1;
304
+}
305
+
306
+static int
307
+sio_oss_getfd(const char *str, unsigned int mode, int nbio)
308
+{
309
+	const char *p;
310
+	char path[DEVPATH_MAX];
311
+	unsigned int devnum;
312
+	int fd, flags;
313
+
314
+	if (strcmp(str, "fallback") == 0) {
315
+		/* On FreeBSD /dev/dsp points to the default unit
316
+		 * selectable with the hw.snd.default_unit sysctl.
317
+		 * Use it as fallback device.
318
+		 */
319
+		snprintf(path, sizeof(path), DEVPATH_PREFIX);
320
+	} else {
321
+		p = _sndio_parsetype(str, "rsnd");
322
+		if (p == NULL) {
323
+			DPRINTF("sio_oss_getfd: %s: \"rsnd\" expected\n", str);
324
+			return -1;
325
+		}
326
+		switch (*p) {
327
+		case '/':
328
+			p++;
329
+			break;
330
+		default:
331
+			DPRINTF("sio_oss_getfd: %s: '/' expected\n", str);
332
+			return -1;
333
+		}
334
+		p = _sndio_parsenum(p, &devnum, 255);
335
+		if (p == NULL || *p != '\0') {
336
+			DPRINTF("sio_oss_getfd: %s: number expected after '/'\n", str);
337
+			return -1;
338
+		}
339
+		snprintf(path, sizeof(path), DEVPATH_PREFIX "%u", devnum);
340
+	}
341
+	if (mode == (SIO_PLAY | SIO_REC))
342
+		flags = O_RDWR;
343
+	else
344
+		flags = (mode & SIO_PLAY) ? O_WRONLY : O_RDONLY;
345
+	while ((fd = open(path, flags | O_NONBLOCK | O_CLOEXEC)) < 0) {
346
+		if (errno == EINTR)
347
+			continue;
348
+		DPERROR(path);
349
+		return -1;
350
+	}
351
+	return fd;
352
+}
353
+
354
+static struct sio_oss_hdl *
355
+sio_oss_fdopen(int fd, unsigned int mode, int nbio)
356
+{
357
+	struct sio_oss_hdl *hdl;
358
+
359
+	hdl = malloc(sizeof(struct sio_oss_hdl));
360
+	if (hdl == NULL)
361
+		return NULL;
362
+	_sio_create(&hdl->sio, &sio_oss_ops, mode, nbio);
363
+
364
+	/* Set default device parameters */
365
+	sio_oss_fmt_to_swpar(AFMT_S16_LE, &hdl->swpar);
366
+	hdl->swpar.msb = 1;
367
+	hdl->swpar.rate = 48000;
368
+	hdl->swpar.bps = SIO_BPS(hdl->swpar.bits);
369
+	hdl->swpar.pchan = hdl->swpar.rchan = 2;
370
+
371
+	hdl->fd = fd;
372
+
373
+	return hdl;
374
+}
375
+
376
+struct sio_hdl *
377
+_sio_oss_open(const char *str, unsigned int mode, int nbio)
378
+{
379
+	struct sio_oss_hdl *hdl;
380
+	int fd;
381
+
382
+	fd = sio_oss_getfd(str, mode, nbio);
383
+	if (fd < 0)
384
+		return NULL;
385
+
386
+	hdl = sio_oss_fdopen(fd, mode, nbio);
387
+	if (hdl != NULL) {
388
+		hdl->devstr = strdup(str);
389
+		return (struct sio_hdl*)hdl;
390
+        }
391
+	while (close(fd) < 0 && errno == EINTR)
392
+		; /* retry */
393
+
394
+	return NULL;
395
+}
396
+
397
+static void
398
+sio_oss_close(struct sio_hdl *sh)
399
+{
400
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
401
+
402
+	while (close(hdl->fd) < 0 && errno == EINTR)
403
+		; /* retry */
404
+	free(hdl->devstr);
405
+	free(hdl);
406
+}
407
+
408
+static int
409
+sio_oss_start(struct sio_hdl *sh)
410
+{
411
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
412
+	int low;
413
+
414
+	hdl->obpf = hdl->sio.par.pchan * hdl->sio.par.bps;
415
+	hdl->ibpf = hdl->sio.par.rchan * hdl->sio.par.bps;
416
+	hdl->isamples = 0;
417
+	hdl->osamples = 0;
418
+	hdl->idelta = 0;
419
+	hdl->odelta = 0;
420
+
421
+	/* Nothing else to do here, device was just (re-)opened in
422
+	 * sio_setpar and OSS starts playing/recording on first
423
+	 * write/read.
424
+	 */
425
+	_sio_onmove_cb(&hdl->sio, 0);
426
+
427
+	return 1;
428
+}
429
+
430
+static int
431
+sio_oss_stop(struct sio_hdl *sh)
432
+{
433
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl*)sh;
434
+	/* Close and reopen device.  This resets CURRENT_IPTR which
435
+	 * allows us to get a semi-accurate recording position */
436
+        if (sio_oss_audio_setpar(hdl, &hdl->swpar) < 0)
437
+		return 0;
438
+	return 1;
439
+}
440
+
441
+static int
442
+sio_oss_setpar(struct sio_hdl *sh, struct sio_par *par)
443
+{
444
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
445
+	struct audio_swpar ap;
446
+
447
+	AUDIO_INITPAR(&ap);
448
+	ap.sig = par->sig;
449
+	ap.le = par->le;
450
+	ap.bits = par->bits;
451
+	ap.bps = par->bps;
452
+	ap.msb = par->msb;
453
+	ap.rate = par->rate;
454
+	if (hdl->sio.mode & SIO_PLAY)
455
+		ap.pchan = par->pchan;
456
+	if (hdl->sio.mode & SIO_REC)
457
+		ap.rchan = par->rchan;
458
+	if (par->round != ~0U && par->appbufsz != ~0U) {
459
+		ap.round = par->round;
460
+		ap.nblks = par->appbufsz / par->round;
461
+	} else if (par->round != ~0U) {
462
+		ap.round = par->round;
463
+		ap.nblks = 2;
464
+	} else if (par->appbufsz != ~0U) {
465
+		ap.round = par->appbufsz / 2;
466
+		ap.nblks = 2;
467
+	}
468
+	if (sio_oss_audio_setpar(hdl, &ap) < 0) {
469
+		DPERROR("AUDIO_SETPAR");
470
+		hdl->sio.eof = 1;
471
+		return 0;
472
+	}
473
+	return 1;
474
+}
475
+
476
+static int
477
+sio_oss_getpar(struct sio_hdl *sh, struct sio_par *par)
478
+{
479
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
480
+	struct audio_swpar ap;
481
+
482
+	if (sio_oss_audio_getpar(hdl, &ap) < 0) {
483
+		DPERROR("AUDIO_GETPAR");
484
+		hdl->sio.eof = 1;
485
+		return 0;
486
+	}
487
+	par->sig = ap.sig;
488
+	par->le = ap.le;
489
+	par->bits = ap.bits;
490
+	par->bps = ap.bps;
491
+	par->msb = ap.msb;
492
+	par->rate = ap.rate;
493
+	par->pchan = ap.pchan;
494
+	par->rchan = ap.rchan;
495
+	par->round = ap.round;
496
+	par->appbufsz = par->bufsz = ap.round * ap.nblks;
497
+	par->xrun = SIO_IGNORE;
498
+	return 1;
499
+}
500
+
501
+static size_t
502
+sio_oss_read(struct sio_hdl *sh, void *buf, size_t len)
503
+{
504
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
505
+	ssize_t n;
506
+
507
+	while ((n = read(hdl->fd, buf, len)) < 0) {
508
+		if (errno == EINTR)
509
+			continue;
510
+		if (errno != EAGAIN) {
511
+			DPERROR("sio_oss_read: read");
512
+			hdl->sio.eof = 1;
513
+		}
514
+		return 0;
515
+	}
516
+	if (n == 0) {
517
+		DPRINTF("sio_oss_read: eof\n");
518
+		hdl->sio.eof = 1;
519
+		return 0;
520
+	}
521
+
522
+	return n;
523
+}
524
+
525
+static size_t
526
+sio_oss_write(struct sio_hdl *sh, const void *buf, size_t len)
527
+{
528
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
529
+	const unsigned char *data = buf;
530
+	ssize_t n, todo;
531
+
532
+	todo = len;
533
+	while ((n = write(hdl->fd, data, todo)) < 0) {
534
+		if (errno == EINTR)
535
+			continue;
536
+		if (errno != EAGAIN) {
537
+			DPERROR("sio_oss_write: write");
538
+			hdl->sio.eof = 1;
539
+		}
540
+		return 0;
541
+	}
542
+
543
+	return n;
544
+}
545
+
546
+static int
547
+sio_oss_nfds(struct sio_hdl *hdl)
548
+{
549
+	return 1;
550
+}
551
+
552
+static int
553
+sio_oss_pollfd(struct sio_hdl *sh, struct pollfd *pfd, int events)
554
+{
555
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
556
+
557
+	pfd->fd = hdl->fd;
558
+	pfd->events = events;
559
+
560
+	return 1;
561
+}
562
+
563
+int
564
+sio_oss_revents(struct sio_hdl *sh, struct pollfd *pfd)
565
+{
566
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
567
+	int delta;
568
+	int revents = pfd->revents;
569
+	long long play_pos, rec_pos;
570
+	oss_count_t optr, iptr;
571
+
572
+	if ((pfd->revents & POLLHUP) ||
573
+	    (pfd->revents & (POLLIN | POLLOUT)) == 0)
574
+		return pfd->revents;
575
+
576
+	if (hdl->sio.mode & SIO_PLAY) {
577
+		if (ioctl(hdl->fd, SNDCTL_DSP_CURRENT_OPTR, &optr) < 0) {
578
+			DPERROR("sio_oss_revents: ");
579
+			hdl->sio.eof = 1;
580
+			return POLLHUP;
581
+		}
582
+		play_pos = optr.samples - optr.fifo_samples;
583
+		delta = play_pos - hdl->osamples;
584
+		hdl->osamples = play_pos;
585
+		hdl->odelta += delta;
586
+		if (!(hdl->sio.mode & SIO_REC)) {
587
+			hdl->idelta += delta;
588
+		}
589
+	}
590
+	if (hdl->sio.mode & SIO_REC) {
591
+		if (ioctl(hdl->fd, SNDCTL_DSP_CURRENT_IPTR, &iptr) < 0) {
592
+			DPERROR("sio_oss_revents: ");
593
+			hdl->sio.eof = 1;
594
+			return POLLHUP;
595
+		}
596
+		rec_pos = iptr.samples - iptr.fifo_samples;
597
+		delta = rec_pos - hdl->isamples;
598
+		hdl->isamples = rec_pos;
599
+		hdl->idelta += delta;
600
+		if (!(hdl->sio.mode & SIO_PLAY)) {
601
+			hdl->odelta += delta;
602
+		}
603
+	}
604
+
605
+	delta = (hdl->idelta > hdl->odelta) ? hdl->idelta : hdl->odelta;
606
+	if (delta > 0) {
607
+		_sio_onmove_cb(&hdl->sio, delta);
608
+		hdl->idelta -= delta;
609
+		hdl->odelta -= delta;
610
+	}
611
+	return revents;
612
+}
613
+
614
+static void
615
+sio_oss_fmt_to_swpar(int fmt, struct audio_swpar *ap) {
616
+	switch(fmt) {
617
+	case AFMT_S8:
618
+		ap->le = 1;
619
+		ap->sig = 1;
620
+		ap->bits = 8;
621
+		break;
622
+	case AFMT_U8:
623
+		ap->le = 1;
624
+		ap->sig = 0;
625
+		ap->bits = 8;
626
+		break;
627
+	case AFMT_S16_LE:
628
+		ap->le = 1;
629
+		ap->sig = 1;
630
+		ap->bits = 16;
631
+		break;
632
+	case AFMT_S16_BE:
633
+		ap->le = 0;
634
+		ap->sig = 1;
635
+		ap->bits = 16;
636
+		break;
637
+	case AFMT_U16_LE:
638
+		ap->le = 1;
639
+		ap->sig = 0;
640
+		ap->bits = 16;
641
+		break;
642
+	case AFMT_U16_BE:
643
+		ap->le = 0;
644
+		ap->sig = 0;
645
+		ap->bits = 16;
646
+		break;
647
+	case AFMT_S24_LE:
648
+		ap->le = 1;
649
+		ap->sig = 1;
650
+		ap->bits = 24;
651
+		break;
652
+	case AFMT_S24_BE:
653
+		ap->le = 0;
654
+		ap->sig = 1;
655
+		ap->bits = 24;
656
+		break;
657
+	case AFMT_U24_LE:
658
+		ap->le = 1;
659
+		ap->sig = 0;
660
+		ap->bits = 24;
661
+		break;
662
+	case AFMT_U24_BE:
663
+		ap->le = 0;
664
+		ap->sig = 0;
665
+		ap->bits = 24;
666
+		break;
667
+	case AFMT_S32_LE:
668
+		ap->le = 1;
669
+		ap->sig = 1;
670
+		ap->bits = 32;
671
+		break;
672
+	case AFMT_S32_BE:
673
+		ap->le = 0;
674
+		ap->sig = 1;
675
+		ap->bits = 32;
676
+		break;
677
+	case AFMT_U32_LE:
678
+		ap->le = 1;
679
+		ap->sig = 0;
680
+		ap->bits = 32;
681
+		break;
682
+	case AFMT_U32_BE:
683
+		ap->le = 0;
684
+		ap->sig = 0;
685
+		ap->bits = 32;
686
+		break;
687
+	}
688
+}
689
+
690
+static int
691
+sio_oss_swpar_to_fmt(struct audio_swpar *ap)
692
+{
693
+	unsigned int bits = ap->bits;
694
+	unsigned int sig = ap->sig;
695
+	unsigned int le = ap->le;
696
+
697
+	switch(bits) {
698
+	case 8:
699
+		if (sig)
700
+			return AFMT_S8;
701
+		else
702
+			return AFMT_U8;
703
+		break;
704
+	case 16:
705
+		if (sig)
706
+			if (le)
707
+				return AFMT_S16_LE;
708
+			else
709
+				return AFMT_S16_BE;
710
+		else
711
+			if (le)
712
+				return AFMT_U16_LE;
713
+			else
714
+				return AFMT_U16_BE;
715
+		break;
716
+		break;
717
+	case 24:
718
+		if (sig)
719
+			if (le)
720
+				return AFMT_S24_LE;
721
+			else
722
+				return AFMT_S24_BE;
723
+		else
724
+			if (le)
725
+				return AFMT_U24_LE;
726
+			else
727
+				return AFMT_U24_BE;
728
+		break;
729
+		break;
730
+	case 32:
731
+		if (sig)
732
+			if (le)
733
+				return AFMT_S32_LE;
734
+			else
735
+				return AFMT_S32_BE;
736
+		else
737
+			if (le)
738
+				return AFMT_U32_LE;
739
+			else
740
+				return AFMT_U32_BE;
741
+		break;
742
+	default:
743
+		if (sig)
744
+			if (SIO_LE_NATIVE)
745
+				return AFMT_S16_LE;
746
+			else
747
+				return AFMT_S16_BE;
748
+		else
749
+			if (SIO_LE_NATIVE)
750
+				return AFMT_U16_LE;
751
+			else
752
+				return AFMT_U16_BE;
753
+	}
754
+}
755
+
756
+static int sio_oss_audio_getpar(struct sio_oss_hdl *hdl, struct audio_swpar *ap)
757
+{
758
+	audio_buf_info bi;
759
+
760
+	*ap = hdl->swpar;
761
+
762
+	return 0;
763
+}
764
+
765
+static int sio_oss_audio_setpar(struct sio_oss_hdl *hdl, struct audio_swpar *ap)
766
+{
767
+	audio_buf_info bi;
768
+	int bufsz;
769
+	int chan;
770
+	int fmt;
771
+	int rate;
772
+
773
+	if (sio_oss_reopen(hdl) < 0) {
774
+		DPERROR("sio_oss_audio_setpar: reopen");
775
+		return -1;
776
+	}
777
+
778
+	ap->msb = ap->msb == -1 ? 0 : ap->msb;
779
+	ap->sig = ap->sig == -1 ? 1 : ap->sig;
780
+	ap->bits = ap->bits == -1 ? ap->bps == -1 ? 16 : ap->bps*8 : ap->bits;
781
+	ap->le = ap->le == -1 ? SIO_LE_NATIVE : ap->le;
782
+	ap->bps = ap->bps == -1 ? SIO_BPS(ap->bits) : ap->bps;
783
+	ap->msb = 0;
784
+	ap->rate = ap->rate == -1 ? 48000 : ap->rate;
785
+
786
+	if (ap->bits < 8)
787
+		ap->bits = 8;
788
+	if (ap->bits > 32)
789
+		ap->bits = 32;
790
+	if (ap->bps < 1)
791
+		ap->bps = 1;
792
+	if (ap->bps > 4)
793
+		ap->bps = 4;
794
+	if (ap->rate < 4000)
795
+		ap->rate = 4000;
796
+	if (ap->rate > 192000)
797
+		ap->rate = 192000;
798
+
799
+	fmt = sio_oss_swpar_to_fmt(ap);
800
+	if (fmt < 0)
801
+		return -1;
802
+	if (ioctl(hdl->fd, SNDCTL_DSP_SETFMT, &fmt) < 0) {
803
+		DPERROR("sio_oss_audio_setpar: SETFMT");
804
+		return -1;
805
+	}
806
+	sio_oss_fmt_to_swpar(fmt, ap);
807
+
808
+	if (ioctl(hdl->fd, SNDCTL_DSP_SPEED, &ap->rate) < 0) {
809
+		DPERROR("sio_oss_audio_setpar: SPEED");
810
+		return -1;
811
+	}
812
+
813
+	chan = ap->pchan == ~0U ? ap->pchan : ap->rchan;
814
+	chan = chan == -1 ? 2 : chan;
815
+	if (ioctl(hdl->fd, SNDCTL_DSP_CHANNELS, &chan) < 0) {
816
+		DPERROR("sio_oss_audio_setpar: CHANNELS");
817
+		return -1;
818
+	}
819
+	ap->pchan = ap->rchan = chan;
820
+
821
+	ap->nblks = ap->nblks <= 0 ? 8 : ap->nblks;
822
+	ap->round = ap->round <= 0 ? 960 : ap->round;
823
+
824
+	hdl->swpar = *ap;
825
+
826
+	return 0;
827
+}
828
+
829
+static int sio_oss_reopen(struct sio_oss_hdl *hdl) {
830
+	/* Reopen device */
831
+	while (close(hdl->fd) < 0 && errno == EINTR)
832
+		; /* retry */
833
+	hdl->fd = sio_oss_getfd(hdl->devstr, hdl->sio.mode, 1);
834
+	if (hdl->fd < 0) {
835
+		DPERROR("sio_oss_audio_setpar: reopen");
836
+		return -1;
837
+	}
838
+	return 0;
839
+}
840
+
841
+#endif /* defined USE_OSS */
(-)a/audio/sndio/files/patch-libsndio_sio__priv.h (-12 lines)
Removed Link Here
1
--- libsndio/sio_priv.h.orig	2015-01-17 23:09:04 UTC
2
+++ libsndio/sio_priv.h
3
@@ -69,6 +69,9 @@ struct sio_hdl *_sio_aucat_open(const ch
4
 #ifdef USE_SUN
5
 struct sio_hdl *_sio_sun_open(const char *, unsigned, int);
6
 #endif
7
+#ifdef USE_OSS
8
+struct sio_hdl *_sio_oss_open(const char *, unsigned, int);
9
+#endif
10
 #ifdef USE_ALSA
11
 struct sio_hdl *_sio_alsa_open(const char *, unsigned, int);
12
 #endif
(-)b/audio/sndio/files/sndiod.in (-11 / +3 lines)
Lines 3-21 Link Here
3
# $FreeBSD$
3
# $FreeBSD$
4
#
4
#
5
# PROVIDE: sndiod
5
# PROVIDE: sndiod
6
# REQUIRE: NETWORKING
6
# REQUIRE: NETWORKING sysctl
7
# BEFORE:  DAEMON
7
# BEFORE:  DAEMON
8
# KEYWORD: shutdown
8
# KEYWORD: shutdown
9
9
10
# By default sndiod will use the audio device from
11
# hw.snd.default_unit.  You can override this by setting sndiod_flags.
12
#
13
# To connect to a remote sndiod use e.g.
14
# sndiod_flags="-f snd@remotehost/0"
15
#
16
# To use /dev/dsp5
17
# sndiod_flags="-f rsnd/5"
18
19
. /etc/rc.subr
10
. /etc/rc.subr
20
11
21
name=sndiod
12
name=sndiod
Lines 23-30 rcvar=sndiod_enable Link Here
23
14
24
load_rc_config $name
15
load_rc_config $name
25
16
17
: ${sndiod_dev="rsnd/$($SYSCTL -n hw.snd.default_unit)"}
26
: ${sndiod_enable="NO"}
18
: ${sndiod_enable="NO"}
27
: ${sndiod_flags="-s default -m mon -s monitor"}
19
: ${sndiod_flags="-f ${sndiod_dev} -c 0:7 -j off -s default -m mon -s monitor"}
28
20
29
command="%%PREFIX%%/bin/sndiod"
21
command="%%PREFIX%%/bin/sndiod"
30
22
(-)b/audio/sndio/pkg-message (-16 / +5 lines)
Lines 1-7 Link Here
1
Sndio's OSS support (i.e. local playback/recording support) is highly
2
experimental.  If you run into problems please file a bug at
3
https://github.com/t6/sndio or send an email to t+sndio@tobik.me.
4
5
Enable the sndiod server with:
1
Enable the sndiod server with:
6
2
7
    sysrc sndiod_enable=YES
3
    sysrc sndiod_enable=YES
Lines 13-31 plays through sndiod: Link Here
13
9
14
    aucat -f snd/0.monitor -o recording.wav
10
    aucat -f snd/0.monitor -o recording.wav
15
11
16
Make sure you override sndiod_flags if this is not wanted:
12
Make sure you override sndiod_flags if this is not wanted.
17
18
    sysrc sndiod_flags=""
19
20
If you want clients to auto-play to your remote sndio server set
21
sndiod_flags accordingly:
22
23
    sysrc sndiod_flags="-f snd@remotehost/0"
24
25
Alternatively you can always set the AUDIODEVICE environment variable
26
so clients know where to stream to:
27
13
28
    export AUDIODEVICE=snd@remotehost/0
14
By default the rc.d script passes '-c 0:7 -j off' to sndiod, so that
15
it uses all 8 virtual channels provided by OSS.  If you override
16
sndiod_flags consider keeping these options, so that multi-channel
17
audio works as you'd expect.
29
18
30
There is little sndio support in the FreeBSD ports tree right now.  If
19
There is little sndio support in the FreeBSD ports tree right now.  If
31
your favourite port is missing support please take a look at the fork
20
your favourite port is missing support please take a look at the fork

Return to bug 214210