FreeBSD Bugzilla – Attachment 173095 Details for
Bug 210124
[NEW PORT] audio/sndio: Small audio and MIDI framework from the OpenBSD project
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
sndio.diff
sndio.diff (text/plain), 35.02 KB, created by
Tobias Kortkamp
on 2016-07-29 14:42:12 UTC
(
hide
)
Description:
sndio.diff
Filename:
MIME Type:
Creator:
Tobias Kortkamp
Created:
2016-07-29 14:42:12 UTC
Size:
35.02 KB
patch
obsolete
>Index: UIDs >=================================================================== >--- UIDs (revision 419237) >+++ UIDs (working copy) >@@ -242,6 +242,7 @@ > stanchion:*:669:667::0:0:Stanchion user:/usr/local/lib/stanchion:/bin/sh > bnetd:*:700:700::0:0:Bnetd user:/nonexistent:/usr/sbin/nologin > fastnetmon:*:701:701::0:0:FastNetMon user:/nonexistent:/usr/sbin/nologin >+_sndio:*:702:702::0:0:sndio privsep:/var/empty:/usr/sbin/nologin > bopm:*:717:717::0:0:Blitzed Open Proxy Monitor:/nonexistent:/bin/sh > _dnscrypt-wrapper:*:718:65534::0:0:dnscrypt-wrapper user:/var/empty:/usr/sbin/nologin > openxpki:*:777:777::0:0:OpenXPKI Owner:/nonexistent:/usr/sbin/nologin >Index: GIDs >=================================================================== >--- GIDs (revision 419237) >+++ GIDs (working copy) >@@ -234,6 +234,7 @@ > riak:*:667: > bnetd:*:700: > fastnetmon:*:701: >+_sndio:*:702: > bopm:*:717: > openxpki:*:777: > zetacoin:*:780: >Index: audio/sndio/Makefile >=================================================================== >--- audio/sndio/Makefile (nonexistent) >+++ audio/sndio/Makefile (working copy) >@@ -0,0 +1,41 @@ >+# Created by: Tobias Kortkamp <t@tobik.me> >+# $FreeBSD$ >+ >+PORTNAME= sndio >+PORTVERSION= 1.1.0 >+CATEGORIES= audio >+MASTER_SITES= http://www.sndio.org/ >+ >+MAINTAINER= t@tobik.me >+COMMENT= Small audio and MIDI framework from the OpenBSD project >+ >+LICENSE= ISCL >+ >+HAS_CONFIGURE= yes >+CONFIGURE_ARGS= --prefix=${PREFIX} --mandir=${PREFIX}/man >+ >+USE_LDCONFIG= yes >+USE_RC_SUBR= sndiod >+ >+.include <bsd.port.pre.mk> >+ >+# FreeBSD 9.x does not have SOCK_CLOEXEC >+.if ${OSVERSION} < 1000000 >+CFLAGS+= -DSOCK_CLOEXEC=0 >+.endif >+ >+USERS= _sndio >+GROUPS= _sndio >+ >+# Parallel build leads to problems, but sndio is very quick to compile >+# as is so not worth fixing >+MAKE_JOBS_UNSAFE= yes >+ >+post-install: >+ @${STRIP_CMD} \ >+ ${STAGEDIR}${PREFIX}/lib/libsndio.so.6.1 \ >+ ${STAGEDIR}${PREFIX}/bin/sndiod \ >+ ${STAGEDIR}${PREFIX}/bin/aucat \ >+ ${STAGEDIR}${PREFIX}/bin/midicat >+ >+.include <bsd.port.post.mk> > >Property changes on: audio/sndio/Makefile >___________________________________________________________________ >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:keywords >## -0,0 +1 ## >+FreeBSD=%H >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property >Index: audio/sndio/distinfo >=================================================================== >--- audio/sndio/distinfo (nonexistent) >+++ audio/sndio/distinfo (working copy) >@@ -0,0 +1,3 @@ >+TIMESTAMP = 1465315037 >+SHA256 (sndio-1.1.0.tar.gz) = fcd7f845ff70f38c2898d737450b8aa3e1bb0afb9d147e8429ef22c0b2c2db57 >+SIZE (sndio-1.1.0.tar.gz) = 121018 > >Property changes on: audio/sndio/distinfo >___________________________________________________________________ >Added: fbsd:nokeywords >## -0,0 +1 ## >+yes >\ No newline at end of property >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property >Index: audio/sndio/files/patch-configure >=================================================================== >--- audio/sndio/files/patch-configure (nonexistent) >+++ audio/sndio/files/patch-configure (working copy) >@@ -0,0 +1,60 @@ >+--- configure.orig 2015-12-15 05:28:04 UTC >++++ configure >+@@ -32,6 +32,7 @@ prefix=/usr/local # where to install s >+ so="libsndio.so.\${MAJ}.\${MIN}" # shared libs to build >+ alsa=no # do we want alsa support ? >+ sun=no # do we want sun support ? >++oss=no # do we want oss support ? >+ rmidi=no # do we want support for raw char dev ? >+ precision=16 # aucat/sndiod arithmetic precision >+ user=_sndio # non-privileged user for sndio daemon >+@@ -71,6 +72,14 @@ case `uname` in >+ defs='-DHAVE_ARC4RANDOM -DHAVE_ISSETUGID \\\ >+ -DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRTONUM' >+ ;; >++ FreeBSD) >++ user=_sndio >++ so="$so libsndio.so" >++ defs='-DHAVE_ARC4RANDOM -DHAVE_ISSETUGID \\\ >++ -DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRTONUM' >++ oss=yes >++ mandir=${prefix}/man >++ ;; >+ esac >+ >+ # shell word separator (none) >+@@ -106,6 +115,12 @@ for i; do >+ --disable-alsa) >+ alsa=no >+ shift;; >++ --enable-oss) >++ oss=yes >++ shift;; >++ --disable-oss) >++ oss=no >++ shift;; >+ --enable-sun) >+ sun=yes >+ shift;; >+@@ -162,6 +177,13 @@ if [ $alsa = yes ]; then >+ fi >+ >+ # >++# if using OSS, add corresponding parameters >++# >++if [ $oss = yes ]; then >++ defs="$defs -DUSE_OSS" >++fi >++ >++# >+ # if using Sun API, add corresponding parameters >+ # >+ if [ $sun = yes ]; then >+@@ -215,6 +237,7 @@ user..................... $user >+ libbsd................... $libbsd >+ precision................ $precision >+ alsa..................... $alsa >++oss...................... $oss >+ sun...................... $sun >+ rmidi.................... $rmidi >+ > >Property changes on: audio/sndio/files/patch-configure >___________________________________________________________________ >Added: fbsd:nokeywords >## -0,0 +1 ## >+yes >\ No newline at end of property >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property >Index: audio/sndio/files/patch-libsndio_Makefile.in >=================================================================== >--- audio/sndio/files/patch-libsndio_Makefile.in (nonexistent) >+++ audio/sndio/files/patch-libsndio_Makefile.in (working copy) >@@ -0,0 +1,17 @@ >+--- libsndio/Makefile.in.orig 2015-12-30 11:54:40 UTC >++++ libsndio/Makefile.in >+@@ -99,7 +99,7 @@ clean: >+ # >+ OBJS = debug.o aucat.o \ >+ mio.o mio_rmidi.o mio_alsa.o mio_aucat.o \ >+-sio.o sio_alsa.o sio_aucat.o sio_sun.o \ >++sio.o sio_alsa.o sio_aucat.o sio_oss.o sio_sun.o \ >+ issetugid.o strlcat.o strlcpy.o strtonum.o >+ >+ .c.o: >+@@ -140,3 +140,5 @@ sio_aucat.o: sio_aucat.c aucat.h amsg.h >+ ../bsd-compat/bsd-compat.h >+ sio_sun.o: sio_sun.c debug.h sio_priv.h sndio.h \ >+ ../bsd-compat/bsd-compat.h >++sio_oss.o: sio_oss.c debug.h sio_priv.h sndio.h \ >++ ../bsd-compat/bsd-compat.h > >Property changes on: audio/sndio/files/patch-libsndio_Makefile.in >___________________________________________________________________ >Added: fbsd:nokeywords >## -0,0 +1 ## >+yes >\ No newline at end of property >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property >Index: audio/sndio/files/patch-libsndio_sio.c >=================================================================== >--- audio/sndio/files/patch-libsndio_sio.c (nonexistent) >+++ audio/sndio/files/patch-libsndio_sio.c (working copy) >@@ -0,0 +1,20 @@ >+--- libsndio/sio.c.orig 2016-01-08 20:51:12 UTC >++++ libsndio/sio.c >+@@ -64,6 +64,8 @@ sio_open(const char *str, unsigned int m >+ return hdl; >+ #if defined(USE_SUN) >+ return _sio_sun_open("rsnd/0", mode, nbio); >++#elif defined(USE_OSS) >++ return _sio_oss_open("rsnd/0", mode, nbio); >+ #elif defined(USE_ALSA) >+ return _sio_alsa_open("rsnd/0", mode, nbio); >+ #else >+@@ -75,6 +77,8 @@ sio_open(const char *str, unsigned int m >+ if (_sndio_parsetype(str, "rsnd")) >+ #if defined(USE_SUN) >+ return _sio_sun_open(str, mode, nbio); >++#elif defined(USE_OSS) >++ return _sio_oss_open(str, mode, nbio); >+ #elif defined(USE_ALSA) >+ return _sio_alsa_open(str, mode, nbio); >+ #else > >Property changes on: audio/sndio/files/patch-libsndio_sio.c >___________________________________________________________________ >Added: fbsd:nokeywords >## -0,0 +1 ## >+yes >\ No newline at end of property >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property >Index: audio/sndio/files/patch-libsndio_sio__oss.c >=================================================================== >--- audio/sndio/files/patch-libsndio_sio__oss.c (nonexistent) >+++ audio/sndio/files/patch-libsndio_sio__oss.c (working copy) >@@ -0,0 +1,893 @@ >+--- libsndio/sio_oss.c.orig 2016-07-29 14:09:21 UTC >++++ libsndio/sio_oss.c >+@@ -0,0 +1,890 @@ >++/* $OpenBSD$ */ >++/* >++ * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> >++ * >++ * Permission to use, copy, modify, and distribute this software for any >++ * purpose with or without fee is hereby granted, provided that the above >++ * copyright notice and this permission notice appear in all copies. >++ * >++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES >++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF >++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR >++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES >++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN >++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF >++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. >++ */ >++ >++#ifdef USE_OSS >++#include <sys/types.h> >++#include <sys/ioctl.h> >++#include <sys/soundcard.h> >++#include <sys/stat.h> >++ >++#include <errno.h> >++#include <fcntl.h> >++#include <limits.h> >++#include <poll.h> >++#include <stdio.h> >++#include <stdlib.h> >++#include <string.h> >++#include <unistd.h> >++ >++#include "debug.h" >++#include "sio_priv.h" >++#include "bsd-compat.h" >++ >++#define DEVPATH_PREFIX "/dev/dsp" >++#define DEVPATH_MAX (1 + \ >++ sizeof(DEVPATH_PREFIX) - 1 + \ >++ sizeof(int) * 3) >++ >++struct audio_pos { >++ unsigned int play_pos; /* total bytes played */ >++ unsigned int play_xrun; /* bytes of silence inserted */ >++ unsigned int rec_pos; /* total bytes recorded */ >++ unsigned int rec_xrun; /* bytes dropped */ >++}; >++ >++#define AUDIO_INITPAR(p) \ >++ (void)memset((void *)(p), 0xff, sizeof(struct audio_swpar)) >++ >++/* >++ * argument to AUDIO_SETPAR and AUDIO_GETPAR ioctls >++ */ >++struct audio_swpar { >++ unsigned int sig; /* if 1, encoding is signed */ >++ unsigned int le; /* if 1, encoding is little-endian */ >++ unsigned int bits; /* bits per sample */ >++ unsigned int bps; /* bytes per sample */ >++ unsigned int msb; /* if 1, bits are msb-aligned */ >++ unsigned int rate; /* common play & rec sample rate */ >++ unsigned int pchan; /* play channels */ >++ unsigned int rchan; /* rec channels */ >++ unsigned int nblks; /* number of blocks in play buffer */ >++ unsigned int round; /* common frames per block */ >++ unsigned int _spare[6]; >++}; >++ >++struct sio_oss_hdl { >++ struct sio_hdl sio; >++ int fd; >++ int filling; >++ unsigned int ibpf, obpf; /* bytes per frame */ >++ unsigned int ibytes, obytes; /* bytes the hw transferred */ >++ unsigned int ierr, oerr; /* frames the hw dropped */ >++ int idelta, odelta; /* position reported to client */ >++ >++ unsigned int play_pos; >++ struct audio_swpar swpar; >++}; >++ >++static void sio_oss_close(struct sio_hdl *); >++static int sio_oss_start(struct sio_hdl *); >++static int sio_oss_stop(struct sio_hdl *); >++static int sio_oss_setpar(struct sio_hdl *, struct sio_par *); >++static int sio_oss_getpar(struct sio_hdl *, struct sio_par *); >++static int sio_oss_getcap(struct sio_hdl *, struct sio_cap *); >++static size_t sio_oss_read(struct sio_hdl *, void *, size_t); >++static size_t sio_oss_write(struct sio_hdl *, const void *, size_t); >++static int sio_oss_nfds(struct sio_hdl *); >++static int sio_oss_pollfd(struct sio_hdl *, struct pollfd *, int); >++static int sio_oss_revents(struct sio_hdl *, struct pollfd *); >++ >++static void sio_oss_fmt_to_swpar(int, struct audio_swpar *); >++static int sio_oss_audio_getpos(struct sio_oss_hdl *, struct audio_pos *); >++static int sio_oss_audio_getpar(struct sio_oss_hdl *, struct audio_swpar *); >++static int sio_oss_audio_setpar(struct sio_oss_hdl *, struct audio_swpar *); >++static int sio_oss_audio_start(struct sio_oss_hdl *); >++static int sio_oss_audio_stop(struct sio_oss_hdl *, int); >++ >++static struct sio_ops sio_oss_ops = { >++ sio_oss_close, >++ sio_oss_setpar, >++ sio_oss_getpar, >++ sio_oss_getcap, >++ sio_oss_write, >++ sio_oss_read, >++ sio_oss_start, >++ sio_oss_stop, >++ sio_oss_nfds, >++ sio_oss_pollfd, >++ sio_oss_revents, >++ NULL, /* setvol */ >++ NULL, /* getvol */ >++}; >++ >++static int >++sio_oss_adjpar(struct sio_oss_hdl *hdl, struct audio_swpar *ap) >++{ >++ if (hdl->sio.eof) >++ return 0; >++ if (sio_oss_audio_setpar(hdl, ap)) { >++ DPERROR("AUDIO_SETPAR"); >++ hdl->sio.eof = 1; >++ return 0; >++ } >++ if (sio_oss_audio_getpar(hdl, ap)) { >++ DPERROR("AUDIO_GETPAR"); >++ hdl->sio.eof = 1; >++ return 0; >++ } >++ return 1; >++} >++ >++/* >++ * try to set the device to the given parameters and check that the >++ * device can use them; return 1 on success, 0 on failure or error >++ */ >++static int >++sio_oss_testpar(struct sio_oss_hdl *hdl, struct sio_enc *enc, >++ unsigned int pchan, unsigned int rchan, unsigned int rate) >++{ >++ struct audio_swpar ap; >++ >++ AUDIO_INITPAR(&ap); >++ if (enc != NULL) { >++ ap.sig = enc->sig; >++ ap.bits = enc->bits; >++ ap.bps = enc->bps; >++ if (ap.bps > 1) >++ ap.le = enc->le; >++ if (ap.bps * 8 > ap.bits) >++ ap.msb = enc->msb; >++ } >++ if (rate) >++ ap.rate = rate; >++ if (pchan && (hdl->sio.mode & SIO_PLAY)) >++ ap.pchan = pchan; >++ if (rchan && (hdl->sio.mode & SIO_REC)) >++ ap.rchan = rchan; >++ if (!sio_oss_adjpar(hdl, &ap)) >++ return 0; >++ if (pchan && ap.pchan != pchan) >++ return 0; >++ if (rchan && ap.rchan != rchan) >++ return 0; >++ if (rate && ap.rate != rate) >++ return 0; >++ if (enc) { >++ if (ap.sig != enc->sig) >++ return 0; >++ if (ap.bits != enc->bits) >++ return 0; >++ if (ap.bps != enc->bps) >++ return 0; >++ if (ap.bps > 1 && ap.le != enc->le) >++ return 0; >++ if (ap.bits < ap.bps * 8 && ap.msb != enc->msb) >++ return 0; >++ } >++ return 1; >++} >++ >++/* >++ * guess device capabilities >++ */ >++static int >++sio_oss_getcap(struct sio_hdl *sh, struct sio_cap *cap) >++{ >++ static unsigned int chans[] = { >++ 1, 2, 4, 6, 8, 10, 12 >++ }; >++ static unsigned int rates[] = { >++ 8000, 11025, 12000, 16000, 22050, 24000, >++ 32000, 44100, 48000, 64000, 88200, 96000 >++ }; >++ static unsigned int encs[] = { >++ 8, 16, 24, 32 >++ }; >++ struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; >++ struct audio_swpar savepar, ap; >++ unsigned int nconf = 0; >++ unsigned int enc_map = 0, rchan_map = 0, pchan_map = 0, rate_map; >++ unsigned int i, j, conf; >++ >++ if (sio_oss_audio_getpar(hdl, &savepar)) { >++ DPERROR("AUDIO_GETPAR"); >++ hdl->sio.eof = 1; >++ return 0; >++ } >++ >++ /* >++ * get a subset of supported encodings >++ */ >++ for (i = 0; i < sizeof(encs) / sizeof(encs[0]); i++) { >++ AUDIO_INITPAR(&ap); >++ ap.bits = encs[i]; >++ ap.sig = (ap.bits > 8) ? 1 : 0; >++ if (!sio_oss_adjpar(hdl, &ap)) >++ return 0; >++ if (ap.bits == encs[i]) { >++ cap->enc[i].sig = ap.sig; >++ cap->enc[i].bits = ap.bits; >++ cap->enc[i].le = ap.le; >++ cap->enc[i].bps = ap.bps; >++ cap->enc[i].msb = ap.msb; >++ enc_map |= 1 << i; >++ } >++ } >++ >++ /* >++ * fill channels >++ * >++ * for now we're lucky: all kernel devices assume that the >++ * number of channels and the encoding are independent so we can >++ * use the current encoding and try various channels. >++ */ >++ if (hdl->sio.mode & SIO_PLAY) { >++ for (i = 0; i < sizeof(chans) / sizeof(chans[0]); i++) { >++ AUDIO_INITPAR(&ap); >++ ap.pchan = chans[i]; >++ if (!sio_oss_adjpar(hdl, &ap)) >++ return 0; >++ if (ap.pchan == chans[i]) { >++ cap->pchan[i] = chans[i]; >++ pchan_map |= (1 << i); >++ } >++ } >++ } >++ if (hdl->sio.mode & SIO_REC) { >++ for (i = 0; i < sizeof(chans) / sizeof(chans[0]); i++) { >++ AUDIO_INITPAR(&ap); >++ ap.pchan = chans[i]; >++ if (!sio_oss_adjpar(hdl, &ap)) >++ return 0; >++ if (ap.rchan == chans[i]) { >++ cap->rchan[i] = chans[i]; >++ rchan_map |= (1 << i); >++ } >++ } >++ } >++ >++ /* >++ * fill rates >++ * >++ * rates are not independent from other parameters (eg. on >++ * uaudio devices), so certain rates may not be allowed with >++ * certain encodings. We have to check rates for all encodings >++ */ >++ for (j = 0; j < sizeof(encs) / sizeof(encs[0]); j++) { >++ rate_map = 0; >++ if ((enc_map & (1 << j)) == 0) >++ continue; >++ for (i = 0; i < sizeof(rates) / sizeof(rates[0]); i++) { >++ if (sio_oss_testpar(hdl, >++ &cap->enc[j], 0, 0, rates[i])) { >++ cap->rate[i] = rates[i]; >++ rate_map |= (1 << i); >++ } >++ } >++ for (conf = 0; conf < nconf; conf++) { >++ if (cap->confs[conf].rate == rate_map) { >++ cap->confs[conf].enc |= (1 << j); >++ break; >++ } >++ } >++ if (conf == nconf) { >++ if (nconf == SIO_NCONF) >++ break; >++ cap->confs[nconf].enc = (1 << j); >++ cap->confs[nconf].pchan = pchan_map; >++ cap->confs[nconf].rchan = rchan_map; >++ cap->confs[nconf].rate = rate_map; >++ nconf++; >++ } >++ } >++ cap->nconf = nconf; >++ >++ if (sio_oss_audio_setpar(hdl, &savepar)) { >++ DPERROR("AUDIO_SETPAR"); >++ hdl->sio.eof = 1; >++ return 0; >++ } >++ return 1; >++} >++ >++static int >++sio_oss_getfd(const char *str, unsigned int mode, int nbio) >++{ >++ const char *p; >++ char path[DEVPATH_MAX]; >++ unsigned int devnum; >++ int fd, flags; >++ >++ p = _sndio_parsetype(str, "rsnd"); >++ if (p == NULL) { >++ DPRINTF("sio_oss_getfd: %s: \"rsnd\" expected\n", str); >++ return -1; >++ } >++ switch (*p) { >++ case '/': >++ p++; >++ break; >++ default: >++ DPRINTF("sio_oss_getfd: %s: '/' expected\n", str); >++ return -1; >++ } >++ p = _sndio_parsenum(p, &devnum, 255); >++ if (p == NULL || *p != '\0') { >++ DPRINTF("sio_oss_getfd: %s: number expected after '/'\n", str); >++ return -1; >++ } >++ snprintf(path, sizeof(path), DEVPATH_PREFIX "%u", devnum); >++ if (mode == (SIO_PLAY | SIO_REC)) >++ flags = O_RDWR; >++ else >++ flags = (mode & SIO_PLAY) ? O_WRONLY : O_RDONLY; >++ while ((fd = open(path, flags | O_NONBLOCK | O_CLOEXEC)) < 0) { >++ if (errno == EINTR) >++ continue; >++ DPERROR(path); >++ return -1; >++ } >++ return fd; >++} >++ >++static struct sio_hdl * >++sio_oss_fdopen(int fd, unsigned int mode, int nbio) >++{ >++ struct sio_oss_hdl *hdl; >++ >++ hdl = malloc(sizeof(struct sio_oss_hdl)); >++ if (hdl == NULL) >++ return NULL; >++ _sio_create(&hdl->sio, &sio_oss_ops, mode, nbio); >++ >++ /* Set default device parameters */ >++ sio_oss_fmt_to_swpar(AFMT_S16_LE, &hdl->swpar); >++ hdl->swpar.msb = 1; >++ hdl->swpar.rate = 44100; >++ hdl->swpar.bps = SIO_BPS(hdl->swpar.bits); >++ hdl->swpar.pchan = hdl->swpar.rchan = 2; >++ hdl->swpar.round = 960; // TODO: >++ hdl->swpar.nblks = 8; // TODO: >++ >++ hdl->fd = fd; >++ hdl->filling = 0; >++ return (struct sio_hdl *)hdl; >++} >++ >++struct sio_hdl * >++_sio_oss_open(const char *str, unsigned int mode, int nbio) >++{ >++ struct sio_hdl *hdl; >++ int fd; >++ >++ fd = sio_oss_getfd(str, mode, nbio); >++ if (fd < 0) >++ return NULL; >++ hdl = sio_oss_fdopen(fd, mode, nbio); >++ if (hdl != NULL) >++ return hdl; >++ while (close(fd) < 0 && errno == EINTR) >++ ; /* retry */ >++ >++ return NULL; >++} >++ >++static void >++sio_oss_close(struct sio_hdl *sh) >++{ >++ struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; >++ >++ while (close(hdl->fd) < 0 && errno == EINTR) >++ ; /* retry */ >++ free(hdl); >++} >++ >++static int >++sio_oss_start(struct sio_hdl *sh) >++{ >++ struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; >++ >++ hdl->obpf = hdl->sio.par.pchan * hdl->sio.par.bps; >++ hdl->ibpf = hdl->sio.par.rchan * hdl->sio.par.bps; >++ hdl->ibytes = 0; >++ hdl->obytes = 0; >++ hdl->ierr = 0; >++ hdl->oerr = 0; >++ hdl->idelta = 0; >++ hdl->odelta = 0; >++ hdl->play_pos = 0; >++ >++ if (hdl->sio.mode & SIO_PLAY) { >++ /* >++ * keep the device paused and let sio_oss_pollfd() trigger the >++ * start later, to avoid buffer underruns >++ */ >++ hdl->filling = 1; >++ } else { >++ /* >++ * no play buffers to fill, start now! >++ */ >++ if (sio_oss_audio_start(hdl) < 0) { >++ DPERROR("AUDIO_START"); >++ hdl->sio.eof = 1; >++ return 0; >++ } >++ _sio_onmove_cb(&hdl->sio, 0); >++ } >++ return 1; >++} >++ >++static int >++sio_oss_stop(struct sio_hdl *sh) >++{ >++ struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; >++ >++ if (hdl->filling) { >++ hdl->filling = 0; >++ return 1; >++ } >++ if (sio_oss_audio_stop(hdl, hdl->fd) < 0) { >++ DPERROR("AUDIO_STOP"); >++ hdl->sio.eof = 1; >++ return 0; >++ } >++ return 1; >++} >++ >++static int >++sio_oss_setpar(struct sio_hdl *sh, struct sio_par *par) >++{ >++ struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; >++ struct audio_swpar ap; >++ >++ AUDIO_INITPAR(&ap); >++ ap.sig = par->sig; >++ ap.le = par->le; >++ ap.bits = par->bits; >++ ap.bps = par->bps; >++ ap.msb = par->msb; >++ ap.rate = par->rate; >++ if (hdl->sio.mode & SIO_PLAY) >++ ap.pchan = par->pchan; >++ if (hdl->sio.mode & SIO_REC) >++ ap.rchan = par->rchan; >++ if (par->round != ~0U && par->appbufsz != ~0U) { >++ ap.round = par->round; >++ ap.nblks = par->appbufsz / par->round; >++ } else if (par->round != ~0U) { >++ ap.round = par->round; >++ ap.nblks = 2; >++ } else if (par->appbufsz != ~0U) { >++ ap.round = par->appbufsz / 2; >++ ap.nblks = 2; >++ } >++ if (sio_oss_audio_setpar(hdl, &ap) < 0) { >++ DPERROR("AUDIO_SETPAR"); >++ hdl->sio.eof = 1; >++ return 0; >++ } >++ return 1; >++} >++ >++static int >++sio_oss_getpar(struct sio_hdl *sh, struct sio_par *par) >++{ >++ struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; >++ struct audio_swpar ap; >++ >++ if (sio_oss_audio_getpar(hdl, &ap) < 0) { >++ DPERROR("AUDIO_GETPAR"); >++ hdl->sio.eof = 1; >++ return 0; >++ } >++ par->sig = ap.sig; >++ par->le = ap.le; >++ par->bits = ap.bits; >++ par->bps = ap.bps; >++ par->msb = ap.msb; >++ par->rate = ap.rate; >++ par->pchan = ap.pchan; >++ par->rchan = ap.rchan; >++ par->round = ap.round; >++ par->appbufsz = par->bufsz = ap.nblks * ap.round; >++ par->xrun = SIO_IGNORE; >++ return 1; >++} >++ >++static size_t >++sio_oss_read(struct sio_hdl *sh, void *buf, size_t len) >++{ >++ struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; >++ ssize_t n; >++ >++ while ((n = read(hdl->fd, buf, len)) < 0) { >++ if (errno == EINTR) >++ continue; >++ if (errno != EAGAIN) { >++ DPERROR("sio_oss_read: read"); >++ hdl->sio.eof = 1; >++ } >++ return 0; >++ } >++ if (n == 0) { >++ DPRINTF("sio_oss_read: eof\n"); >++ hdl->sio.eof = 1; >++ return 0; >++ } >++ return n; >++} >++ >++static size_t >++sio_oss_write(struct sio_hdl *sh, const void *buf, size_t len) >++{ >++ struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; >++ const unsigned char *data = buf; >++ ssize_t n, todo; >++ >++ todo = len; >++ while ((n = write(hdl->fd, data, todo)) < 0) { >++ if (errno == EINTR) >++ continue; >++ if (errno != EAGAIN) { >++ DPERROR("sio_oss_write: write"); >++ hdl->sio.eof = 1; >++ } >++ return 0; >++ } >++ >++ hdl->play_pos += n; >++ >++ return n; >++} >++ >++static int >++sio_oss_nfds(struct sio_hdl *hdl) >++{ >++ return 1; >++} >++ >++static int >++sio_oss_pollfd(struct sio_hdl *sh, struct pollfd *pfd, int events) >++{ >++ struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; >++ >++ pfd->fd = hdl->fd; >++ pfd->events = events; >++ if (hdl->filling && hdl->sio.wused == hdl->sio.par.bufsz * >++ hdl->sio.par.pchan * hdl->sio.par.bps) { >++ hdl->filling = 0; >++ if (sio_oss_audio_start(hdl) < 0) { >++ DPERROR("AUDIO_START"); >++ hdl->sio.eof = 1; >++ return 0; >++ } >++ _sio_onmove_cb(&hdl->sio, 0); >++ } >++ return 1; >++} >++ >++int >++sio_oss_revents(struct sio_hdl *sh, struct pollfd *pfd) >++{ >++ struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; >++ struct audio_pos ap; >++ int dierr = 0, doerr = 0, offset, delta; >++ int revents = pfd->revents; >++ >++ if ((pfd->revents & POLLHUP) || >++ (pfd->revents & (POLLIN | POLLOUT)) == 0) >++ return pfd->revents; >++ if (sio_oss_audio_getpos(hdl, &ap) < 0) { >++ DPERROR("sio_oss_revents: GETPOS"); >++ hdl->sio.eof = 1; >++ return POLLHUP; >++ } >++ if (hdl->sio.mode & SIO_PLAY) { >++ delta = (ap.play_pos - hdl->obytes) / hdl->obpf; >++ doerr = (ap.play_xrun - hdl->oerr) / hdl->obpf; >++ hdl->obytes = ap.play_pos; >++ hdl->oerr = ap.play_xrun; >++ hdl->odelta += delta; >++ if (!(hdl->sio.mode & SIO_REC)) { >++ hdl->idelta += delta; >++ dierr = doerr; >++ } >++ if (doerr > 0) >++ DPRINTFN(2, "play xrun %d\n", doerr); >++ } >++ if (hdl->sio.mode & SIO_REC) { >++ delta = (ap.rec_pos - hdl->ibytes) / hdl->ibpf; >++ dierr = (ap.rec_xrun - hdl->ierr) / hdl->ibpf; >++ hdl->ibytes = ap.rec_pos; >++ hdl->ierr = ap.rec_xrun; >++ hdl->idelta += delta; >++ if (!(hdl->sio.mode & SIO_PLAY)) { >++ hdl->odelta += delta; >++ doerr = dierr; >++ } >++ if (dierr > 0) >++ DPRINTFN(2, "rec xrun %d\n", dierr); >++ } >++ >++ /* >++ * GETPOS reports positions including xruns, >++ * so we have to substract to get the real position >++ */ >++ hdl->idelta -= dierr; >++ hdl->odelta -= doerr; >++ >++ offset = doerr - dierr; >++ if (offset > 0) { >++ hdl->sio.rdrop += offset * hdl->ibpf; >++ hdl->idelta -= offset; >++ DPRINTFN(2, "will drop %d and pause %d\n", offset, doerr); >++ } else if (offset < 0) { >++ hdl->sio.wsil += -offset * hdl->obpf; >++ hdl->odelta -= -offset; >++ DPRINTFN(2, "will insert %d and pause %d\n", -offset, dierr); >++ } >++ >++ delta = (hdl->idelta > hdl->odelta) ? hdl->idelta : hdl->odelta; >++ if (delta > 0) { >++ _sio_onmove_cb(&hdl->sio, delta); >++ hdl->idelta -= delta; >++ hdl->odelta -= delta; >++ } >++ return revents; >++} >++ >++static int >++sio_oss_audio_getpos(struct sio_oss_hdl *hdl, struct audio_pos *ap) >++{ >++ count_info cio, cii; >++ oss_count_t optr; >++ >++ ap->play_pos = hdl->play_pos / hdl->sio.par.bps; >++ ap->play_xrun = 0; >++ >++ if (ioctl(hdl->fd, SNDCTL_DSP_GETIPTR, &cii) < 0) { >++ DPERROR("sio_oss_getpos: GETIPTR"); >++ return -1; >++ } >++ >++ ap->rec_pos = cii.bytes; >++ ap->rec_xrun = 0; >++ >++ return 0; >++} >++ >++static void >++sio_oss_fmt_to_swpar(int fmt, struct audio_swpar *ap) { >++ switch(fmt) { >++ case AFMT_S8: >++ ap->le = 1; >++ ap->sig = 1; >++ ap->bits = 8; >++ break; >++ case AFMT_U8: >++ ap->le = 1; >++ ap->sig = 0; >++ ap->bits = 8; >++ break; >++ case AFMT_S16_LE: >++ ap->le = 1; >++ ap->sig = 1; >++ ap->bits = 16; >++ break; >++ case AFMT_S16_BE: >++ ap->le = 0; >++ ap->sig = 1; >++ ap->bits = 16; >++ break; >++ case AFMT_U16_LE: >++ ap->le = 1; >++ ap->sig = 0; >++ ap->bits = 16; >++ break; >++ case AFMT_U16_BE: >++ ap->le = 0; >++ ap->sig = 0; >++ ap->bits = 16; >++ break; >++ case AFMT_S24_LE: >++ ap->le = 1; >++ ap->sig = 1; >++ ap->bits = 24; >++ break; >++ case AFMT_S24_BE: >++ ap->le = 0; >++ ap->sig = 1; >++ ap->bits = 24; >++ break; >++ case AFMT_U24_LE: >++ ap->le = 1; >++ ap->sig = 0; >++ ap->bits = 24; >++ break; >++ case AFMT_U24_BE: >++ ap->le = 0; >++ ap->sig = 0; >++ ap->bits = 24; >++ break; >++ case AFMT_S32_LE: >++ ap->le = 1; >++ ap->sig = 1; >++ ap->bits = 32; >++ break; >++ case AFMT_S32_BE: >++ ap->le = 0; >++ ap->sig = 1; >++ ap->bits = 32; >++ break; >++ case AFMT_U32_LE: >++ ap->le = 1; >++ ap->sig = 0; >++ ap->bits = 32; >++ break; >++ case AFMT_U32_BE: >++ ap->le = 0; >++ ap->sig = 0; >++ ap->bits = 32; >++ break; >++ } >++} >++ >++static int >++sio_oss_swpar_to_fmt(struct audio_swpar *ap) >++{ >++ unsigned int bits = ap->bits; >++ unsigned int sig = ap->sig; >++ unsigned int le = ap->le; >++ >++ switch(bits) { >++ case 8: >++ if (sig) >++ return AFMT_S8; >++ else >++ return AFMT_U8; >++ break; >++ case 16: >++ if (sig) >++ if (le) >++ return AFMT_S16_LE; >++ else >++ return AFMT_S16_BE; >++ else >++ if (le) >++ return AFMT_U16_LE; >++ else >++ return AFMT_U16_BE; >++ break; >++ break; >++ case 24: >++ if (sig) >++ if (le) >++ return AFMT_S24_LE; >++ else >++ return AFMT_S24_BE; >++ else >++ if (le) >++ return AFMT_U24_LE; >++ else >++ return AFMT_U24_BE; >++ break; >++ break; >++ case 32: >++ if (sig) >++ if (le) >++ return AFMT_S32_LE; >++ else >++ return AFMT_S32_BE; >++ else >++ if (le) >++ return AFMT_U32_LE; >++ else >++ return AFMT_U32_BE; >++ break; >++ default: >++ if (sig) >++ if (SIO_LE_NATIVE) >++ return AFMT_S16_LE; >++ else >++ return AFMT_S16_BE; >++ else >++ if (SIO_LE_NATIVE) >++ return AFMT_U16_LE; >++ else >++ return AFMT_U16_BE; >++ } >++} >++ >++static int sio_oss_audio_getpar(struct sio_oss_hdl *hdl, struct audio_swpar *ap) >++{ >++ audio_buf_info bi; >++ >++ *ap = hdl->swpar; >++ >++ return 0; >++} >++ >++static int sio_oss_audio_setpar(struct sio_oss_hdl *hdl, struct audio_swpar *ap) >++{ >++ int fmt = sio_oss_swpar_to_fmt(ap); >++ if (fmt < 0) >++ return -1; >++ >++ if (ioctl(hdl->fd, SNDCTL_DSP_SETFMT, &fmt) < 0) >++ return -1; >++ >++ sio_oss_fmt_to_swpar(fmt, ap); >++ >++ if (ioctl(hdl->fd, SNDCTL_DSP_SPEED, &ap->rate) < 0) >++ return -1; >++ >++ ap->bps = SIO_BPS(ap->bits); >++ ap->msb = 0; >++ >++ int chan = (hdl->sio.mode & SIO_PLAY) ? ap->pchan : ap->rchan; >++ if (ioctl(hdl->fd, SNDCTL_DSP_CHANNELS, &chan) < 0) >++ return -1; >++ >++ ap->pchan = ap->rchan = chan; >++ >++ hdl->swpar = *ap; >++ >++ return 0; >++} >++ >++static int sio_oss_audio_start(struct sio_oss_hdl *hdl) { >++ // Empty playback buffer >++ if (ioctl(hdl->fd, SNDCTL_DSP_SKIP, NULL) < 0) { >++ DPERROR("SNDCTL_DSP_SKIP"); >++ return -1; >++ } >++ >++ int trigger; >++ >++ if (hdl->sio.mode & SIO_PLAY) { >++ trigger = PCM_ENABLE_OUTPUT; >++ } >++ if (hdl->sio.mode & SIO_REC) { >++ trigger = PCM_ENABLE_INPUT; >++ } // TODO: >++ >++ if (ioctl(hdl->fd, SNDCTL_DSP_SETTRIGGER, &trigger)) { >++ DPERROR("sio_oss_start: SETTRIGGER"); >++ return -1; >++ } >++ >++ return 0; >++} >++ >++static int sio_oss_audio_stop(struct sio_oss_hdl *hdl, int fd) { >++ /* Block until buffer is played */ >++ if (ioctl(hdl->fd, SNDCTL_DSP_SYNC, NULL) < 0) { >++ return -1; >++ } >++ >++ // TODO: Check mode and use HALT_{IN,OUT}PUT >++ if (ioctl(hdl->fd, SNDCTL_DSP_HALT, NULL) < 0) { >++ return -1; >++ } >++ >++ return 0; >++} >++ >++#endif /* defined USE_OSS */ > >Property changes on: audio/sndio/files/patch-libsndio_sio__oss.c >___________________________________________________________________ >Added: fbsd:nokeywords >## -0,0 +1 ## >+yes >\ No newline at end of property >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property >Index: audio/sndio/files/patch-libsndio_sio__priv.h >=================================================================== >--- audio/sndio/files/patch-libsndio_sio__priv.h (nonexistent) >+++ audio/sndio/files/patch-libsndio_sio__priv.h (working copy) >@@ -0,0 +1,12 @@ >+--- libsndio/sio_priv.h.orig 2015-01-17 23:09:04 UTC >++++ libsndio/sio_priv.h >+@@ -69,6 +69,9 @@ struct sio_hdl *_sio_aucat_open(const ch >+ #ifdef USE_SUN >+ struct sio_hdl *_sio_sun_open(const char *, unsigned, int); >+ #endif >++#ifdef USE_OSS >++struct sio_hdl *_sio_oss_open(const char *, unsigned, int); >++#endif >+ #ifdef USE_ALSA >+ struct sio_hdl *_sio_alsa_open(const char *, unsigned, int); >+ #endif > >Property changes on: audio/sndio/files/patch-libsndio_sio__priv.h >___________________________________________________________________ >Added: fbsd:nokeywords >## -0,0 +1 ## >+yes >\ No newline at end of property >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property >Index: audio/sndio/files/sndiod.in >=================================================================== >--- audio/sndio/files/sndiod.in (nonexistent) >+++ audio/sndio/files/sndiod.in (working copy) >@@ -0,0 +1,32 @@ >+#!/bin/sh >+# >+# $FreeBSD$ >+# >+# PROVIDE: sndiod >+# REQUIRE: NETWORKING sysctl >+# BEFORE: DAEMON >+# KEYWORD: shutdown >+ >+# By default sndiod will use the audio device from >+# hw.snd.default_unit. You can override this by setting sndiod_flags. >+# >+# To connect to a remote sndiod use e.g. >+# sndiod_flags="-f snd@remotehost/0" >+# >+# To use /dev/dsp5 >+# sndiod_flags="-f rsnd/5" >+ >+. /etc/rc.subr >+ >+name=sndiod >+rcvar=sndiod_enable >+ >+load_rc_config $name >+ >+_sndiod_devnum=$($SYSCTL -n hw.snd.default_unit) >+: ${sndiod_enable="NO"} >+: ${sndiod_flags="-f rsnd/$_sndiod_devnum"} >+ >+command="%%PREFIX%%/bin/sndiod" >+ >+run_rc_command "$1" > >Property changes on: audio/sndio/files/sndiod.in >___________________________________________________________________ >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property >Index: audio/sndio/pkg-descr >=================================================================== >--- audio/sndio/pkg-descr (nonexistent) >+++ audio/sndio/pkg-descr (working copy) >@@ -0,0 +1,11 @@ >+Sndio is a small audio and MIDI framework part of the OpenBSD >+project. >+ >+It provides an lightweight audio & MIDI server and a fully documented >+user-space API to access either the server or directly the hardware in >+a uniform way. Sndio is designed to work for desktop applications, >+but pays special attention to synchronization mechanisms and >+reliability required by music applications. Reliability through >+simplicity are part of the project goals. >+ >+WWW: http://www.sndio.org/ > >Property changes on: audio/sndio/pkg-descr >___________________________________________________________________ >Added: fbsd:nokeywords >## -0,0 +1 ## >+yes >\ No newline at end of property >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property >Index: audio/sndio/pkg-message >=================================================================== >--- audio/sndio/pkg-message (nonexistent) >+++ audio/sndio/pkg-message (working copy) >@@ -0,0 +1,29 @@ >+sndio's OSS support (i.e. local playback support) is highly >+experimental. If you run into problems please file a bug at >+https://github.com/t6/sndio or send an email to t+sndio@tobik.me. >+ >+The recommended way to use this port is to have a remote sndio server >+running on a Linux or OpenBSD host. >+ >+If you want clients to auto-play to your remote sndio server, enable >+sndiod with: >+ >+ sysrc sndiod_enable=YES sndiod_flags="-f snd@remotehost/0" >+ service sndiod start >+ >+For local playback simply enabling the sndiod server will suffice >+ >+ sysrc sndiod_enable=YES >+ >+Alternatively set the AUDIODEVICE environment variable so clients know >+where to stream to >+ >+ export AUDIODEVICE=snd@remotehost/0 >+ >+There is no sndio support in the official FreeBSD ports tree yet. The >+fork at https://github.com/t6/freebsd-port-sndio contains patches that >+enable sndio support in important ports. >+ >+audio/pulseaudio-module-sndio is a PulseAudio module that allows you >+to play to your sndio server. This is useful for ports that have >+PulseAudio support but no direct sndio support. > >Property changes on: audio/sndio/pkg-message >___________________________________________________________________ >Added: fbsd:nokeywords >## -0,0 +1 ## >+yes >\ No newline at end of property >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property >Index: audio/sndio/pkg-plist >=================================================================== >--- audio/sndio/pkg-plist (nonexistent) >+++ audio/sndio/pkg-plist (working copy) >@@ -0,0 +1,35 @@ >+bin/aucat >+bin/midicat >+bin/sndiod >+include/sndio.h >+lib/libsndio.so >+lib/libsndio.so.6.1 >+man/man1/aucat.1.gz >+man/man1/midicat.1.gz >+man/man3/mio_close.3.gz >+man/man3/mio_eof.3.gz >+man/man3/mio_nfds.3.gz >+man/man3/mio_open.3.gz >+man/man3/mio_pollfd.3.gz >+man/man3/mio_read.3.gz >+man/man3/mio_revents.3.gz >+man/man3/mio_write.3.gz >+man/man3/sio_close.3.gz >+man/man3/sio_eof.3.gz >+man/man3/sio_getcap.3.gz >+man/man3/sio_getpar.3.gz >+man/man3/sio_initpar.3.gz >+man/man3/sio_nfds.3.gz >+man/man3/sio_onmove.3.gz >+man/man3/sio_onvol.3.gz >+man/man3/sio_open.3.gz >+man/man3/sio_pollfd.3.gz >+man/man3/sio_read.3.gz >+man/man3/sio_revents.3.gz >+man/man3/sio_setpar.3.gz >+man/man3/sio_setvol.3.gz >+man/man3/sio_start.3.gz >+man/man3/sio_stop.3.gz >+man/man3/sio_write.3.gz >+man/man7/sndio.7.gz >+man/man8/sndiod.8.gz > >Property changes on: audio/sndio/pkg-plist >___________________________________________________________________ >Added: fbsd:nokeywords >## -0,0 +1 ## >+yes >\ No newline at end of property >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
tobik
:
maintainer-approval+
Actions:
View
|
Diff
Attachments on
bug 210124
:
171185
|
171186
|
171187
|
172828
| 173095