View | Details | Raw Unified | Return to bug 212007
Collapse All | Expand All

(-)Makefile (+1 lines)
Lines 3-8 Link Here
3
3
4
PORTNAME=	sndio
4
PORTNAME=	sndio
5
PORTVERSION=	1.1.0
5
PORTVERSION=	1.1.0
6
PORTREVISION=	1
6
CATEGORIES=	audio
7
CATEGORIES=	audio
7
MASTER_SITES=	http://www.sndio.org/
8
MASTER_SITES=	http://www.sndio.org/
8
9
(-)files/patch-configure (-5 / +6 lines)
Lines 8-14 Link Here
8
 rmidi=no				# do we want support for raw char dev ?
8
 rmidi=no				# do we want support for raw char dev ?
9
 precision=16				# aucat/sndiod arithmetic precision
9
 precision=16				# aucat/sndiod arithmetic precision
10
 user=_sndio				# non-privileged user for sndio daemon
10
 user=_sndio				# non-privileged user for sndio daemon
11
@@ -71,6 +72,14 @@ case `uname` in
11
@@ -71,6 +72,15 @@ case `uname` in
12
 		defs='-DHAVE_ARC4RANDOM -DHAVE_ISSETUGID \\\
12
 		defs='-DHAVE_ARC4RANDOM -DHAVE_ISSETUGID \\\
13
 		-DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRTONUM'
13
 		-DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRTONUM'
14
 		;;
14
 		;;
Lines 16-22 Link Here
16
+		user=_sndio
16
+		user=_sndio
17
+		so="$so libsndio.so"
17
+		so="$so libsndio.so"
18
+		defs='-DHAVE_ARC4RANDOM -DHAVE_ISSETUGID \\\
18
+		defs='-DHAVE_ARC4RANDOM -DHAVE_ISSETUGID \\\
19
+		-DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRTONUM'
19
+		-DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRTONUM \\\
20
+		-DDEFAULT_DEV=\\"fallback\\"'
20
+		oss=yes
21
+		oss=yes
21
+		mandir=${prefix}/man
22
+		mandir=${prefix}/man
22
+		;;
23
+		;;
Lines 23-29 Link Here
23
 esac
24
 esac
24
 
25
 
25
 # shell word separator (none)
26
 # shell word separator (none)
26
@@ -106,6 +115,12 @@ for i; do
27
@@ -106,6 +116,12 @@ for i; do
27
 	--disable-alsa)
28
 	--disable-alsa)
28
 		alsa=no
29
 		alsa=no
29
 		shift;;
30
 		shift;;
Lines 36-42 Link Here
36
 	--enable-sun)
37
 	--enable-sun)
37
 		sun=yes
38
 		sun=yes
38
 		shift;;
39
 		shift;;
39
@@ -162,6 +177,13 @@ if [ $alsa = yes ]; then
40
@@ -162,6 +178,13 @@ if [ $alsa = yes ]; then
40
 fi
41
 fi
41
 
42
 
42
 #
43
 #
Lines 50-56 Link Here
50
 # if using Sun API, add corresponding parameters
51
 # if using Sun API, add corresponding parameters
51
 #
52
 #
52
 if [ $sun = yes ]; then
53
 if [ $sun = yes ]; then
53
@@ -215,6 +237,7 @@ user..................... $user
54
@@ -215,6 +238,7 @@ user..................... $user
54
 libbsd................... $libbsd
55
 libbsd................... $libbsd
55
 precision................ $precision
56
 precision................ $precision
56
 alsa..................... $alsa
57
 alsa..................... $alsa
(-)files/patch-libsndio_sio.c (-3 / +11 lines)
Lines 1-15 Link Here
1
--- libsndio/sio.c.orig	2016-01-08 20:51:12 UTC
1
--- libsndio/sio.c.orig	2016-01-08 20:51:12 UTC
2
+++ libsndio/sio.c
2
+++ libsndio/sio.c
3
@@ -64,6 +64,8 @@ sio_open(const char *str, unsigned int m
3
@@ -64,17 +64,25 @@ sio_open(const char *str, unsigned int m
4
 			return hdl;
4
 			return hdl;
5
 #if defined(USE_SUN)
5
 #if defined(USE_SUN)
6
 		return _sio_sun_open("rsnd/0", mode, nbio);
6
 		return _sio_sun_open("rsnd/0", mode, nbio);
7
+#elif defined(USE_OSS)
7
+#elif defined(USE_OSS)
8
+		return _sio_oss_open("rsnd/0", mode, nbio);
8
+		return _sio_oss_open("fallback", mode, nbio);
9
 #elif defined(USE_ALSA)
9
 #elif defined(USE_ALSA)
10
 		return _sio_alsa_open("rsnd/0", mode, nbio);
10
 		return _sio_alsa_open("rsnd/0", mode, nbio);
11
 #else
11
 #else
12
@@ -75,6 +77,8 @@ sio_open(const char *str, unsigned int m
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);
13
 	if (_sndio_parsetype(str, "rsnd"))
21
 	if (_sndio_parsetype(str, "rsnd"))
14
 #if defined(USE_SUN)
22
 #if defined(USE_SUN)
15
 		return _sio_sun_open(str, mode, nbio);
23
 		return _sio_sun_open(str, mode, nbio);
(-)files/patch-libsndio_sio__oss.c (-189 / +137 lines)
Lines 1-9 Link Here
1
--- libsndio/sio_oss.c.orig	2016-07-29 14:09:21 UTC
1
--- libsndio/sio_oss.c.orig	2016-08-20 02:30:22 UTC
2
+++ libsndio/sio_oss.c
2
+++ libsndio/sio_oss.c
3
@@ -0,0 +1,890 @@
3
@@ -0,0 +1,838 @@
4
+/*	$OpenBSD$	*/
4
+/*	$OpenBSD$	*/
5
+/*
5
+/*
6
+ * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
6
+ * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
7
+ * Copyright (c) 2016 Tobias Kortkamp <t@tobik.me>
7
+ *
8
+ *
8
+ * Permission to use, copy, modify, and distribute this software for any
9
+ * Permission to use, copy, modify, and distribute this software for any
9
+ * purpose with or without fee is hereby granted, provided that the above
10
+ * purpose with or without fee is hereby granted, provided that the above
Lines 21-26 Link Here
21
+#ifdef USE_OSS
22
+#ifdef USE_OSS
22
+#include <sys/types.h>
23
+#include <sys/types.h>
23
+#include <sys/ioctl.h>
24
+#include <sys/ioctl.h>
25
+#include <sys/param.h>
24
+#include <sys/soundcard.h>
26
+#include <sys/soundcard.h>
25
+#include <sys/stat.h>
27
+#include <sys/stat.h>
26
+
28
+
Lines 42-54 Link Here
42
+	sizeof(DEVPATH_PREFIX) - 1 +	\
44
+	sizeof(DEVPATH_PREFIX) - 1 +	\
43
+	sizeof(int) * 3)
45
+	sizeof(int) * 3)
44
+
46
+
45
+struct audio_pos {
46
+	unsigned int play_pos;  /* total bytes played */
47
+	unsigned int play_xrun; /* bytes of silence inserted */
48
+	unsigned int rec_pos;   /* total bytes recorded */
49
+	unsigned int rec_xrun;  /* bytes dropped */
50
+};
51
+
52
+#define AUDIO_INITPAR(p)						\
47
+#define AUDIO_INITPAR(p)						\
53
+	(void)memset((void *)(p), 0xff, sizeof(struct audio_swpar))
48
+	(void)memset((void *)(p), 0xff, sizeof(struct audio_swpar))
54
+
49
+
Lines 72-84 Link Here
72
+struct sio_oss_hdl {
67
+struct sio_oss_hdl {
73
+	struct sio_hdl sio;
68
+	struct sio_hdl sio;
74
+	int fd;
69
+	int fd;
75
+	int filling;
76
+	unsigned int ibpf, obpf;	/* bytes per frame */
70
+	unsigned int ibpf, obpf;	/* bytes per frame */
77
+	unsigned int ibytes, obytes;	/* bytes the hw transferred */
71
+	unsigned int isamples;
78
+	unsigned int ierr, oerr;	/* frames the hw dropped */
72
+	unsigned int osamples;
79
+	int idelta, odelta;		/* position reported to client */
73
+	int idelta, odelta;		/* position reported to client */
80
+
74
+
81
+	unsigned int play_pos;
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
+	 */
82
+	struct audio_swpar swpar;
80
+	struct audio_swpar swpar;
83
+};
81
+};
84
+
82
+
Lines 95-105 Link Here
95
+static int sio_oss_revents(struct sio_hdl *, struct pollfd *);
93
+static int sio_oss_revents(struct sio_hdl *, struct pollfd *);
96
+
94
+
97
+static void sio_oss_fmt_to_swpar(int, struct audio_swpar *);
95
+static void sio_oss_fmt_to_swpar(int, struct audio_swpar *);
98
+static int sio_oss_audio_getpos(struct sio_oss_hdl *, struct audio_pos *);
99
+static int sio_oss_audio_getpar(struct sio_oss_hdl *, struct audio_swpar *);
96
+static int sio_oss_audio_getpar(struct sio_oss_hdl *, struct audio_swpar *);
100
+static int sio_oss_audio_setpar(struct sio_oss_hdl *, struct audio_swpar *);
97
+static int sio_oss_audio_setpar(struct sio_oss_hdl *, struct audio_swpar *);
101
+static int sio_oss_audio_start(struct sio_oss_hdl *);
98
+static int sio_oss_reopen(struct sio_oss_hdl *);
102
+static int sio_oss_audio_stop(struct sio_oss_hdl *, int);
103
+
99
+
104
+static struct sio_ops sio_oss_ops = {
100
+static struct sio_ops sio_oss_ops = {
105
+	sio_oss_close,
101
+	sio_oss_close,
Lines 315-339 Link Here
315
+	unsigned int devnum;
311
+	unsigned int devnum;
316
+	int fd, flags;
312
+	int fd, flags;
317
+
313
+
318
+	p = _sndio_parsetype(str, "rsnd");
314
+	if (strcmp(str, "fallback") == 0) {
319
+	if (p == NULL) {
315
+		/* On FreeBSD /dev/dsp points to the default unit
320
+		DPRINTF("sio_oss_getfd: %s: \"rsnd\" expected\n", str);
316
+		 * selectable with the hw.snd.default_unit sysctl.
321
+		return -1;
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);
322
+	}
340
+	}
323
+	switch (*p) {
324
+	case '/':
325
+		p++;
326
+		break;
327
+	default:
328
+		DPRINTF("sio_oss_getfd: %s: '/' expected\n", str);
329
+		return -1;
330
+	}
331
+	p = _sndio_parsenum(p, &devnum, 255);
332
+	if (p == NULL || *p != '\0') {
333
+		DPRINTF("sio_oss_getfd: %s: number expected after '/'\n", str);
334
+		return -1;
335
+	}
336
+	snprintf(path, sizeof(path), DEVPATH_PREFIX "%u", devnum);
337
+	if (mode == (SIO_PLAY | SIO_REC))
341
+	if (mode == (SIO_PLAY | SIO_REC))
338
+		flags = O_RDWR;
342
+		flags = O_RDWR;
339
+	else
343
+	else
Lines 347-353 Link Here
347
+	return fd;
351
+	return fd;
348
+}
352
+}
349
+
353
+
350
+static struct sio_hdl *
354
+static struct sio_oss_hdl *
351
+sio_oss_fdopen(int fd, unsigned int mode, int nbio)
355
+sio_oss_fdopen(int fd, unsigned int mode, int nbio)
352
+{
356
+{
353
+	struct sio_oss_hdl *hdl;
357
+	struct sio_oss_hdl *hdl;
Lines 360-388 Link Here
360
+	/* Set default device parameters */
364
+	/* Set default device parameters */
361
+	sio_oss_fmt_to_swpar(AFMT_S16_LE, &hdl->swpar);
365
+	sio_oss_fmt_to_swpar(AFMT_S16_LE, &hdl->swpar);
362
+	hdl->swpar.msb = 1;
366
+	hdl->swpar.msb = 1;
363
+	hdl->swpar.rate = 44100;
367
+	hdl->swpar.rate = 48000;
364
+	hdl->swpar.bps = SIO_BPS(hdl->swpar.bits);
368
+	hdl->swpar.bps = SIO_BPS(hdl->swpar.bits);
365
+	hdl->swpar.pchan = hdl->swpar.rchan = 2;
369
+	hdl->swpar.pchan = hdl->swpar.rchan = 2;
366
+	hdl->swpar.round = 960; // TODO:
367
+	hdl->swpar.nblks = 8; // TODO:
368
+
370
+
369
+	hdl->fd = fd;
371
+	hdl->fd = fd;
370
+	hdl->filling = 0;
372
+
371
+	return (struct sio_hdl *)hdl;
373
+	return hdl;
372
+}
374
+}
373
+
375
+
374
+struct sio_hdl *
376
+struct sio_hdl *
375
+_sio_oss_open(const char *str, unsigned int mode, int nbio)
377
+_sio_oss_open(const char *str, unsigned int mode, int nbio)
376
+{
378
+{
377
+	struct sio_hdl *hdl;
379
+	struct sio_oss_hdl *hdl;
378
+	int fd;
380
+	int fd;
379
+
381
+
380
+	fd = sio_oss_getfd(str, mode, nbio);
382
+	fd = sio_oss_getfd(str, mode, nbio);
381
+	if (fd < 0)
383
+	if (fd < 0)
382
+		return NULL;
384
+		return NULL;
385
+
383
+	hdl = sio_oss_fdopen(fd, mode, nbio);
386
+	hdl = sio_oss_fdopen(fd, mode, nbio);
384
+	if (hdl != NULL)
387
+	if (hdl != NULL) {
385
+		return hdl;
388
+		hdl->devstr = strdup(str);
389
+		return (struct sio_hdl*)hdl;
390
+        }
386
+	while (close(fd) < 0 && errno == EINTR)
391
+	while (close(fd) < 0 && errno == EINTR)
387
+		; /* retry */
392
+		; /* retry */
388
+
393
+
Lines 396-401 Link Here
396
+
401
+
397
+	while (close(hdl->fd) < 0 && errno == EINTR)
402
+	while (close(hdl->fd) < 0 && errno == EINTR)
398
+		; /* retry */
403
+		; /* retry */
404
+	free(hdl->devstr);
399
+	free(hdl);
405
+	free(hdl);
400
+}
406
+}
401
+
407
+
Lines 403-436 Link Here
403
+sio_oss_start(struct sio_hdl *sh)
409
+sio_oss_start(struct sio_hdl *sh)
404
+{
410
+{
405
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
411
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
412
+	int low;
406
+
413
+
407
+	hdl->obpf = hdl->sio.par.pchan * hdl->sio.par.bps;
414
+	hdl->obpf = hdl->sio.par.pchan * hdl->sio.par.bps;
408
+	hdl->ibpf = hdl->sio.par.rchan * hdl->sio.par.bps;
415
+	hdl->ibpf = hdl->sio.par.rchan * hdl->sio.par.bps;
409
+	hdl->ibytes = 0;
416
+	hdl->isamples = 0;
410
+	hdl->obytes = 0;
417
+	hdl->osamples = 0;
411
+	hdl->ierr = 0;
412
+	hdl->oerr = 0;
413
+	hdl->idelta = 0;
418
+	hdl->idelta = 0;
414
+	hdl->odelta = 0;
419
+	hdl->odelta = 0;
415
+	hdl->play_pos = 0;
416
+
420
+
417
+	if (hdl->sio.mode & SIO_PLAY) {
421
+	/* Nothing else to do here, device was just (re-)opened in
418
+		/*
422
+	 * sio_setpar and OSS starts playing/recording on first
419
+		 * keep the device paused and let sio_oss_pollfd() trigger the
423
+	 * write/read.
420
+		 * start later, to avoid buffer underruns
424
+	 */
421
+		 */
425
+	_sio_onmove_cb(&hdl->sio, 0);
422
+		hdl->filling = 1;
426
+
423
+	} else {
424
+		/*
425
+		 * no play buffers to fill, start now!
426
+		 */
427
+		if (sio_oss_audio_start(hdl) < 0) {
428
+			DPERROR("AUDIO_START");
429
+			hdl->sio.eof = 1;
430
+			return 0;
431
+		}
432
+		_sio_onmove_cb(&hdl->sio, 0);
433
+	}
434
+	return 1;
427
+	return 1;
435
+}
428
+}
436
+
429
+
Lines 437-453 Link Here
437
+static int
430
+static int
438
+sio_oss_stop(struct sio_hdl *sh)
431
+sio_oss_stop(struct sio_hdl *sh)
439
+{
432
+{
440
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
433
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl*)sh;
441
+
434
+	/* Close and reopen device.  This resets CURRENT_IPTR which
442
+	if (hdl->filling) {
435
+	 * allows us to get a semi-accurate recording position */
443
+		hdl->filling = 0;
436
+        if (sio_oss_audio_setpar(hdl, &hdl->swpar) < 0)
444
+		return 1;
445
+	}
446
+	if (sio_oss_audio_stop(hdl, hdl->fd) < 0) {
447
+		DPERROR("AUDIO_STOP");
448
+		hdl->sio.eof = 1;
449
+		return 0;
437
+		return 0;
450
+	}
451
+	return 1;
438
+	return 1;
452
+}
439
+}
453
+
440
+
Lines 506-512 Link Here
506
+	par->pchan = ap.pchan;
493
+	par->pchan = ap.pchan;
507
+	par->rchan = ap.rchan;
494
+	par->rchan = ap.rchan;
508
+	par->round = ap.round;
495
+	par->round = ap.round;
509
+	par->appbufsz = par->bufsz = ap.nblks * ap.round;
496
+	par->appbufsz = par->bufsz = ap.round * ap.nblks;
510
+	par->xrun = SIO_IGNORE;
497
+	par->xrun = SIO_IGNORE;
511
+	return 1;
498
+	return 1;
512
+}
499
+}
Lines 531-536 Link Here
531
+		hdl->sio.eof = 1;
518
+		hdl->sio.eof = 1;
532
+		return 0;
519
+		return 0;
533
+	}
520
+	}
521
+
534
+	return n;
522
+	return n;
535
+}
523
+}
536
+
524
+
Lines 552-559 Link Here
552
+		return 0;
540
+		return 0;
553
+	}
541
+	}
554
+
542
+
555
+	hdl->play_pos += n;
556
+
557
+	return n;
543
+	return n;
558
+}
544
+}
559
+
545
+
Lines 570-585 Link Here
570
+
556
+
571
+	pfd->fd = hdl->fd;
557
+	pfd->fd = hdl->fd;
572
+	pfd->events = events;
558
+	pfd->events = events;
573
+	if (hdl->filling && hdl->sio.wused == hdl->sio.par.bufsz *
559
+
574
+		hdl->sio.par.pchan * hdl->sio.par.bps) {
575
+		hdl->filling = 0;
576
+		if (sio_oss_audio_start(hdl) < 0) {
577
+			DPERROR("AUDIO_START");
578
+			hdl->sio.eof = 1;
579
+			return 0;
580
+		}
581
+		_sio_onmove_cb(&hdl->sio, 0);
582
+	}
583
+	return 1;
560
+	return 1;
584
+}
561
+}
585
+
562
+
Lines 587-649 Link Here
587
+sio_oss_revents(struct sio_hdl *sh, struct pollfd *pfd)
564
+sio_oss_revents(struct sio_hdl *sh, struct pollfd *pfd)
588
+{
565
+{
589
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
566
+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
590
+	struct audio_pos ap;
567
+	int delta;
591
+	int dierr = 0, doerr = 0, offset, delta;
592
+	int revents = pfd->revents;
568
+	int revents = pfd->revents;
569
+	long long play_pos, rec_pos;
570
+	oss_count_t optr, iptr;
593
+
571
+
594
+	if ((pfd->revents & POLLHUP) ||
572
+	if ((pfd->revents & POLLHUP) ||
595
+	    (pfd->revents & (POLLIN | POLLOUT)) == 0)
573
+	    (pfd->revents & (POLLIN | POLLOUT)) == 0)
596
+		return pfd->revents;
574
+		return pfd->revents;
597
+	if (sio_oss_audio_getpos(hdl, &ap) < 0) {
575
+
598
+		DPERROR("sio_oss_revents: GETPOS");
599
+		hdl->sio.eof = 1;
600
+		return POLLHUP;
601
+	}
602
+	if (hdl->sio.mode & SIO_PLAY) {
576
+	if (hdl->sio.mode & SIO_PLAY) {
603
+		delta = (ap.play_pos - hdl->obytes) / hdl->obpf;
577
+		if (ioctl(hdl->fd, SNDCTL_DSP_CURRENT_OPTR, &optr) < 0) {
604
+		doerr = (ap.play_xrun - hdl->oerr) / hdl->obpf;
578
+			DPERROR("sio_oss_revents: ");
605
+		hdl->obytes = ap.play_pos;
579
+			hdl->sio.eof = 1;
606
+		hdl->oerr = ap.play_xrun;
580
+			return POLLHUP;
581
+		}
582
+		play_pos = optr.samples - optr.fifo_samples;
583
+		delta = play_pos - hdl->osamples;
584
+		hdl->osamples = play_pos;
607
+		hdl->odelta += delta;
585
+		hdl->odelta += delta;
608
+		if (!(hdl->sio.mode & SIO_REC)) {
586
+		if (!(hdl->sio.mode & SIO_REC)) {
609
+			hdl->idelta += delta;
587
+			hdl->idelta += delta;
610
+			dierr = doerr;
611
+		}
588
+		}
612
+		if (doerr > 0)
613
+			DPRINTFN(2, "play xrun %d\n", doerr);
614
+	}
589
+	}
615
+	if (hdl->sio.mode & SIO_REC) {
590
+	if (hdl->sio.mode & SIO_REC) {
616
+		delta = (ap.rec_pos - hdl->ibytes) / hdl->ibpf;
591
+		if (ioctl(hdl->fd, SNDCTL_DSP_CURRENT_IPTR, &iptr) < 0) {
617
+		dierr = (ap.rec_xrun - hdl->ierr) / hdl->ibpf;
592
+			DPERROR("sio_oss_revents: ");
618
+		hdl->ibytes = ap.rec_pos;
593
+			hdl->sio.eof = 1;
619
+		hdl->ierr = ap.rec_xrun;
594
+			return POLLHUP;
595
+		}
596
+		rec_pos = iptr.samples - iptr.fifo_samples;
597
+		delta = rec_pos - hdl->isamples;
598
+		hdl->isamples = rec_pos;
620
+		hdl->idelta += delta;
599
+		hdl->idelta += delta;
621
+		if (!(hdl->sio.mode & SIO_PLAY)) {
600
+		if (!(hdl->sio.mode & SIO_PLAY)) {
622
+			hdl->odelta += delta;
601
+			hdl->odelta += delta;
623
+			doerr = dierr;
624
+		}
602
+		}
625
+		if (dierr > 0)
626
+			DPRINTFN(2, "rec xrun %d\n", dierr);
627
+	}
603
+	}
628
+
604
+
629
+	/*
630
+	 * GETPOS reports positions including xruns,
631
+	 * so we have to substract to get the real position
632
+	 */
633
+	hdl->idelta -= dierr;
634
+	hdl->odelta -= doerr;
635
+
636
+	offset = doerr - dierr;
637
+	if (offset > 0) {
638
+		hdl->sio.rdrop += offset * hdl->ibpf;
639
+		hdl->idelta -= offset;
640
+		DPRINTFN(2, "will drop %d and pause %d\n", offset, doerr);
641
+	} else if (offset < 0) {
642
+		hdl->sio.wsil += -offset * hdl->obpf;
643
+		hdl->odelta -= -offset;
644
+		DPRINTFN(2, "will insert %d and pause %d\n", -offset, dierr);
645
+	}
646
+
647
+	delta = (hdl->idelta > hdl->odelta) ? hdl->idelta : hdl->odelta;
605
+	delta = (hdl->idelta > hdl->odelta) ? hdl->idelta : hdl->odelta;
648
+	if (delta > 0) {
606
+	if (delta > 0) {
649
+		_sio_onmove_cb(&hdl->sio, delta);
607
+		_sio_onmove_cb(&hdl->sio, delta);
Lines 653-678 Link Here
653
+	return revents;
611
+	return revents;
654
+}
612
+}
655
+
613
+
656
+static int
657
+sio_oss_audio_getpos(struct sio_oss_hdl *hdl, struct audio_pos *ap)
658
+{
659
+	count_info cio, cii;
660
+	oss_count_t optr;
661
+
662
+	ap->play_pos = hdl->play_pos / hdl->sio.par.bps;
663
+	ap->play_xrun = 0;
664
+
665
+	if (ioctl(hdl->fd, SNDCTL_DSP_GETIPTR, &cii) < 0) {
666
+		DPERROR("sio_oss_getpos: GETIPTR");
667
+		return -1;
668
+	}
669
+
670
+	ap->rec_pos = cii.bytes;
671
+	ap->rec_xrun = 0;
672
+
673
+	return 0;
674
+}
675
+
676
+static void
614
+static void
677
+sio_oss_fmt_to_swpar(int fmt, struct audio_swpar *ap) {
615
+sio_oss_fmt_to_swpar(int fmt, struct audio_swpar *ap) {
678
+	switch(fmt) {
616
+	switch(fmt) {
Lines 826-892 Link Here
826
+
764
+
827
+static int sio_oss_audio_setpar(struct sio_oss_hdl *hdl, struct audio_swpar *ap)
765
+static int sio_oss_audio_setpar(struct sio_oss_hdl *hdl, struct audio_swpar *ap)
828
+{
766
+{
829
+	int fmt = sio_oss_swpar_to_fmt(ap);
767
+	audio_buf_info bi;
830
+	if (fmt < 0)
768
+	int bufsz;
831
+		return -1;
769
+	int chan;
770
+	int fmt;
771
+	int rate;
832
+
772
+
833
+	if (ioctl(hdl->fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
773
+	if (sio_oss_reopen(hdl) < 0) {
774
+		DPERROR("sio_oss_audio_setpar: reopen");
834
+		return -1;
775
+		return -1;
776
+	}
835
+
777
+
836
+	sio_oss_fmt_to_swpar(fmt, ap);
778
+	ap->msb = ap->msb == -1 ? 0 : ap->msb;
837
+
779
+	ap->sig = ap->sig == -1 ? 1 : ap->sig;
838
+	if (ioctl(hdl->fd, SNDCTL_DSP_SPEED, &ap->rate) < 0)
780
+	ap->bits = ap->bits == -1 ? ap->bps == -1 ? 16 : ap->bps*8 : ap->bits;
839
+		return -1;
781
+	ap->le = ap->le == -1 ? SIO_LE_NATIVE : ap->le;
840
+
782
+	ap->bps = ap->bps == -1 ? SIO_BPS(ap->bits) : ap->bps;
841
+	ap->bps = SIO_BPS(ap->bits);
842
+	ap->msb = 0;
783
+	ap->msb = 0;
784
+	ap->rate = ap->rate == -1 ? 48000 : ap->rate;
843
+
785
+
844
+	int chan = (hdl->sio.mode & SIO_PLAY) ? ap->pchan : ap->rchan;
786
+	if (ap->bits < 8)
845
+	if (ioctl(hdl->fd, SNDCTL_DSP_CHANNELS, &chan) < 0)
787
+		ap->bits = 8;
846
+		return -1;
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;
847
+
798
+
848
+	ap->pchan = ap->rchan = chan;
799
+	fmt = sio_oss_swpar_to_fmt(ap);
849
+
800
+	if (fmt < 0)
850
+	hdl->swpar = *ap;
851
+
852
+	return 0;
853
+}
854
+
855
+static int sio_oss_audio_start(struct sio_oss_hdl *hdl) {
856
+	// Empty playback buffer
857
+	if (ioctl(hdl->fd, SNDCTL_DSP_SKIP, NULL) < 0) {
858
+		DPERROR("SNDCTL_DSP_SKIP");
859
+		return -1;
801
+		return -1;
802
+	if (ioctl(hdl->fd, SNDCTL_DSP_SETFMT, &fmt) < 0) {
803
+		DPERROR("sio_oss_audio_setpar: SETFMT");
804
+		return -1;
860
+	}
805
+	}
806
+	sio_oss_fmt_to_swpar(fmt, ap);
861
+
807
+
862
+	int trigger;
808
+	if (ioctl(hdl->fd, SNDCTL_DSP_SPEED, &ap->rate) < 0) {
863
+
809
+		DPERROR("sio_oss_audio_setpar: SPEED");
864
+	if (hdl->sio.mode & SIO_PLAY) {
810
+		return -1;
865
+		trigger = PCM_ENABLE_OUTPUT;
866
+	}
811
+	}
867
+	if (hdl->sio.mode & SIO_REC) {
868
+		trigger = PCM_ENABLE_INPUT;
869
+	} // TODO:
870
+
812
+
871
+	if (ioctl(hdl->fd, SNDCTL_DSP_SETTRIGGER, &trigger)) {
813
+	chan = ap->pchan == ~0U ? ap->pchan : ap->rchan;
872
+		DPERROR("sio_oss_start: SETTRIGGER");
814
+	chan = chan == -1 ? 2 : chan;
815
+	if (ioctl(hdl->fd, SNDCTL_DSP_CHANNELS, &chan) < 0) {
816
+		DPERROR("sio_oss_audio_setpar: CHANNELS");
873
+		return -1;
817
+		return -1;
874
+	}
818
+	}
819
+	ap->pchan = ap->rchan = chan;
875
+
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
+
876
+	return 0;
826
+	return 0;
877
+}
827
+}
878
+
828
+
879
+static int sio_oss_audio_stop(struct sio_oss_hdl *hdl, int fd) {
829
+static int sio_oss_reopen(struct sio_oss_hdl *hdl) {
880
+	/* Block until buffer is played */
830
+	/* Reopen device */
881
+	if (ioctl(hdl->fd, SNDCTL_DSP_SYNC, NULL) < 0) {
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");
882
+		return -1;
836
+		return -1;
883
+	}
837
+	}
884
+
885
+	// TODO: Check mode and use HALT_{IN,OUT}PUT
886
+	if (ioctl(hdl->fd, SNDCTL_DSP_HALT, NULL) < 0) {
887
+		return -1;
888
+	}
889
+
890
+	return 0;
838
+	return 0;
891
+}
839
+}
892
+
840
+
(-)files/sndiod.in (-3 / +2 lines)
Lines 3-9 Link Here
3
# $FreeBSD$
3
# $FreeBSD$
4
#
4
#
5
# PROVIDE: sndiod
5
# PROVIDE: sndiod
6
# REQUIRE: NETWORKING sysctl
6
# REQUIRE: NETWORKING
7
# BEFORE:  DAEMON
7
# BEFORE:  DAEMON
8
# KEYWORD: shutdown
8
# KEYWORD: shutdown
9
9
Lines 23-31 Link Here
23
23
24
load_rc_config $name
24
load_rc_config $name
25
25
26
_sndiod_devnum=$($SYSCTL -n hw.snd.default_unit)
27
: ${sndiod_enable="NO"}
26
: ${sndiod_enable="NO"}
28
: ${sndiod_flags="-f rsnd/$_sndiod_devnum"}
27
: ${sndiod_flags="-s default -m mon -s monitor"}
29
28
30
command="%%PREFIX%%/bin/sndiod"
29
command="%%PREFIX%%/bin/sndiod"
31
30
(-)pkg-message (-14 / +23 lines)
Lines 1-28 Link Here
1
sndio's OSS support (i.e. local playback support) is highly
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
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.
3
https://github.com/t6/sndio or send an email to t+sndio@tobik.me.
4
4
5
The recommended way to use this port is to have a remote sndio server
5
Enable the sndiod server with:
6
running on a Linux or OpenBSD host.
7
6
8
If you want clients to auto-play to your remote sndio server, enable
7
    sysrc sndiod_enable=YES
9
sndiod with:
10
11
    sysrc sndiod_enable=YES sndiod_flags="-f snd@remotehost/0"
12
    service sndiod start
8
    service sndiod start
13
9
14
For local playback simply enabling the sndiod server will suffice
10
Please note that by default sndiod is configured with a monitoring
11
sub-device i.e. a device through which you can record everything that
12
plays through sndiod:
15
13
16
    sysrc sndiod_enable=YES
14
    aucat -f snd/0.monitor -o recording.wav
17
15
18
Alternatively set the AUDIODEVICE environment variable so clients know
16
Make sure you override sndiod_flags if this is not wanted:
19
where to stream to
20
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
21
    export AUDIODEVICE=snd@remotehost/0
28
    export AUDIODEVICE=snd@remotehost/0
22
29
23
There is no sndio support in the official FreeBSD ports tree yet.  The
30
There is little sndio support in the FreeBSD ports tree right now.  If
24
fork at https://github.com/t6/freebsd-port-sndio contains patches that
31
your favourite port is missing support please take a look at the fork
25
enable sndio support in important ports.
32
at https://github.com/t6/freebsd-ports-sndio and
33
https://github.com/t6/freebsd-ports-sndio/wiki/Status which contains
34
patches that enable sndio support in various ports.
26
35
27
audio/pulseaudio-module-sndio is a PulseAudio module that allows you
36
audio/pulseaudio-module-sndio is a PulseAudio module that allows you
28
to play to your sndio server.  This is useful for ports that have
37
to play to your sndio server.  This is useful for ports that have

Return to bug 212007