From: ratchov Date: Fri, 29 Apr 2022 08:30:48 +0000 (+0000) Subject: Add sio_flush(3) function to stop playback immediately X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=ec8a3410fbf86966d4e84ce53a01458ea2cd5c80;p=openbsd Add sio_flush(3) function to stop playback immediately The new sio_flush(3) functions works the same way as sio_stop(3), except that it doesn't wait for play buffer to be drained. Instead, it discards its contents and returns immediately. --- diff --git a/include/sndio.h b/include/sndio.h index 03550a0b23f..04c7336dd03 100644 --- a/include/sndio.h +++ b/include/sndio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sndio.h,v 1.13 2020/06/28 05:21:38 ratchov Exp $ */ +/* $OpenBSD: sndio.h,v 1.14 2022/04/29 08:30:48 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov * @@ -164,6 +164,7 @@ size_t sio_write(struct sio_hdl *, const void *, size_t); size_t sio_read(struct sio_hdl *, void *, size_t); int sio_start(struct sio_hdl *); int sio_stop(struct sio_hdl *); +int sio_flush(struct sio_hdl *); int sio_nfds(struct sio_hdl *); int sio_pollfd(struct sio_hdl *, struct pollfd *, int); int sio_revents(struct sio_hdl *, struct pollfd *); diff --git a/lib/libsndio/Symbols.map b/lib/libsndio/Symbols.map index a83e63d6a97..cf8920610b9 100644 --- a/lib/libsndio/Symbols.map +++ b/lib/libsndio/Symbols.map @@ -11,6 +11,7 @@ sio_read; sio_start; sio_stop; + sio_flush; sio_nfds; sio_pollfd; sio_revents; diff --git a/lib/libsndio/amsg.h b/lib/libsndio/amsg.h index 6dfb6954764..6d1a185fcbf 100644 --- a/lib/libsndio/amsg.h +++ b/lib/libsndio/amsg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: amsg.h,v 1.14 2021/11/01 14:43:24 ratchov Exp $ */ +/* $OpenBSD: amsg.h,v 1.15 2022/04/29 08:30:48 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov * @@ -96,6 +96,9 @@ struct amsg { #define AMSG_DATAMAX 0x1000 uint32_t size; } data; + struct amsg_stop { + uint8_t drain; + } stop; struct amsg_ts { int32_t delta; } ts; diff --git a/lib/libsndio/shlib_version b/lib/libsndio/shlib_version index b39addfcc64..a0ace4f32f2 100644 --- a/lib/libsndio/shlib_version +++ b/lib/libsndio/shlib_version @@ -1,2 +1,2 @@ major=7 -minor=1 +minor=2 diff --git a/lib/libsndio/sio.c b/lib/libsndio/sio.c index 430f88469c5..57fb757f3d7 100644 --- a/lib/libsndio/sio.c +++ b/lib/libsndio/sio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sio.c,v 1.26 2021/11/01 14:43:24 ratchov Exp $ */ +/* $OpenBSD: sio.c,v 1.27 2022/04/29 08:30:48 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov * @@ -129,6 +129,8 @@ sio_start(struct sio_hdl *hdl) int sio_stop(struct sio_hdl *hdl) { + if (hdl->ops->stop == NULL) + return sio_flush(hdl); if (hdl->eof) { DPRINTF("sio_stop: eof\n"); return 0; @@ -148,6 +150,28 @@ sio_stop(struct sio_hdl *hdl) return 1; } +int +sio_flush(struct sio_hdl *hdl) +{ + if (hdl->eof) { + DPRINTF("sio_flush: eof\n"); + return 0; + } + if (!hdl->started) { + DPRINTF("sio_flush: not started\n"); + hdl->eof = 1; + return 0; + } + if (!hdl->ops->flush(hdl)) + return 0; +#ifdef DEBUG + DPRINTFN(2, "libsndio: polls: %llu, samples = %llu\n", + hdl->pollcnt, hdl->cpos); +#endif + hdl->started = 0; + return 1; +} + int sio_setpar(struct sio_hdl *hdl, struct sio_par *par) { diff --git a/lib/libsndio/sio_aucat.c b/lib/libsndio/sio_aucat.c index 74a1ecdd13e..24c4cd61bc9 100644 --- a/lib/libsndio/sio_aucat.c +++ b/lib/libsndio/sio_aucat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sio_aucat.c,v 1.20 2016/01/09 08:27:24 ratchov Exp $ */ +/* $OpenBSD: sio_aucat.c,v 1.21 2022/04/29 08:30:48 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov * @@ -49,6 +49,7 @@ struct sio_aucat_hdl { static void sio_aucat_close(struct sio_hdl *); static int sio_aucat_start(struct sio_hdl *); static int sio_aucat_stop(struct sio_hdl *); +static int sio_aucat_flush(struct sio_hdl *); static int sio_aucat_setpar(struct sio_hdl *, struct sio_par *); static int sio_aucat_getpar(struct sio_hdl *, struct sio_par *); static int sio_aucat_getcap(struct sio_hdl *, struct sio_cap *); @@ -69,6 +70,7 @@ static struct sio_ops sio_aucat_ops = { sio_aucat_read, sio_aucat_start, sio_aucat_stop, + sio_aucat_flush, sio_aucat_nfds, sio_aucat_pollfd, sio_aucat_revents, @@ -207,7 +209,7 @@ sio_aucat_start(struct sio_hdl *sh) } static int -sio_aucat_stop(struct sio_hdl *sh) +sio_aucat_drain(struct sio_hdl *sh, int drain) { #define ZERO_MAX 0x400 static unsigned char zero[ZERO_MAX]; @@ -240,6 +242,7 @@ sio_aucat_stop(struct sio_hdl *sh) */ AMSG_INIT(&hdl->aucat.wmsg); hdl->aucat.wmsg.cmd = htonl(AMSG_STOP); + hdl->aucat.wmsg.u.stop.drain = drain; hdl->aucat.wtodo = sizeof(struct amsg); if (!_aucat_wmsg(&hdl->aucat, &hdl->sio.eof)) return 0; @@ -262,6 +265,18 @@ sio_aucat_stop(struct sio_hdl *sh) return 1; } +static int +sio_aucat_stop(struct sio_hdl *sh) +{ + return sio_aucat_drain(sh, 1); +} + +static int +sio_aucat_flush(struct sio_hdl *sh) +{ + return sio_aucat_drain(sh, 0); +} + static int sio_aucat_setpar(struct sio_hdl *sh, struct sio_par *par) { diff --git a/lib/libsndio/sio_open.3 b/lib/libsndio/sio_open.3 index 3bbe4895fde..836bb66a01e 100644 --- a/lib/libsndio/sio_open.3 +++ b/lib/libsndio/sio_open.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sio_open.3,v 1.53 2022/03/31 17:27:18 naddy Exp $ +.\" $OpenBSD: sio_open.3,v 1.54 2022/04/29 08:30:48 ratchov Exp $ .\" .\" Copyright (c) 2007 Alexandre Ratchov .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: March 31 2022 $ +.Dd $Mdocdate: April 29 2022 $ .Dt SIO_OPEN 3 .Os .Sh NAME @@ -25,6 +25,7 @@ .Nm sio_getcap , .Nm sio_start , .Nm sio_stop , +.Nm sio_flush , .Nm sio_read , .Nm sio_write , .Nm sio_onmove , @@ -53,6 +54,8 @@ .Fn sio_start "struct sio_hdl *hdl" .Ft "int" .Fn sio_stop "struct sio_hdl *hdl" +.Ft "int" +.Fn sio_flush "struct sio_hdl *hdl" .Ft "size_t" .Fn sio_read "struct sio_hdl *hdl" "void *addr" "size_t nbytes" .Ft "size_t" @@ -257,6 +260,8 @@ Parameters cannot be changed after .Fn sio_start has been called, .Fn sio_stop +or +.Fn sio_flush must be called before parameters can be changed. .Pp If the device is exposed by the @@ -410,6 +415,14 @@ If samples to play are queued but playback hasn't started yet then playback is forced immediately; playback will actually stop once the buffer is drained. In no case are samples in the play buffer discarded. +.Pp +The +.Fn sio_flush +function stops playback and recording immediately, +possibly discarding play buffer contents, and puts the audio subsystem +in the same state as before +.Fn sio_start +is called. .Ss Playing and recording When record mode is selected, the .Fn sio_read @@ -748,6 +761,7 @@ The .Fn sio_getcap , .Fn sio_start , .Fn sio_stop , +.Fn sio_flush , and .Fn sio_setvol functions return 1 on success and 0 on failure. @@ -828,7 +842,8 @@ The .Fn sio_getpar , .Fn sio_getcap , .Fn sio_start , +.Fn sio_stop , and -.Fn sio_stop +.Fn sio_flush functions may block for a very short period of time, thus they should be avoided in code sections where blocking is not desirable. diff --git a/lib/libsndio/sio_priv.h b/lib/libsndio/sio_priv.h index fd310142793..9f143320862 100644 --- a/lib/libsndio/sio_priv.h +++ b/lib/libsndio/sio_priv.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sio_priv.h,v 1.9 2015/01/16 16:48:52 deraadt Exp $ */ +/* $OpenBSD: sio_priv.h,v 1.10 2022/04/29 08:30:48 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov * @@ -58,6 +58,7 @@ struct sio_ops { size_t (*read)(struct sio_hdl *, void *, size_t); int (*start)(struct sio_hdl *); int (*stop)(struct sio_hdl *); + int (*flush)(struct sio_hdl *); int (*nfds)(struct sio_hdl *); int (*pollfd)(struct sio_hdl *, struct pollfd *, int); int (*revents)(struct sio_hdl *, struct pollfd *); diff --git a/lib/libsndio/sio_sun.c b/lib/libsndio/sio_sun.c index 5ff939b7de4..28636485b16 100644 --- a/lib/libsndio/sio_sun.c +++ b/lib/libsndio/sio_sun.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sio_sun.c,v 1.28 2019/06/28 13:32:42 deraadt Exp $ */ +/* $OpenBSD: sio_sun.c,v 1.29 2022/04/29 08:30:48 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov * @@ -48,7 +48,7 @@ struct sio_sun_hdl { static void sio_sun_close(struct sio_hdl *); static int sio_sun_start(struct sio_hdl *); -static int sio_sun_stop(struct sio_hdl *); +static int sio_sun_flush(struct sio_hdl *); static int sio_sun_setpar(struct sio_hdl *, struct sio_par *); static int sio_sun_getpar(struct sio_hdl *, struct sio_par *); static int sio_sun_getcap(struct sio_hdl *, struct sio_cap *); @@ -66,7 +66,8 @@ static struct sio_ops sio_sun_ops = { sio_sun_write, sio_sun_read, sio_sun_start, - sio_sun_stop, + NULL, + sio_sun_flush, sio_sun_nfds, sio_sun_pollfd, sio_sun_revents, @@ -395,7 +396,7 @@ sio_sun_start(struct sio_hdl *sh) } static int -sio_sun_stop(struct sio_hdl *sh) +sio_sun_flush(struct sio_hdl *sh) { struct sio_sun_hdl *hdl = (struct sio_sun_hdl *)sh; diff --git a/usr.bin/sndiod/siofile.c b/usr.bin/sndiod/siofile.c index 48bf8623c25..e437c2a1c99 100644 --- a/usr.bin/sndiod/siofile.c +++ b/usr.bin/sndiod/siofile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: siofile.c,v 1.25 2021/11/01 14:43:25 ratchov Exp $ */ +/* $OpenBSD: siofile.c,v 1.26 2022/04/29 08:30:48 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov * @@ -317,7 +317,7 @@ dev_sio_start(struct dev *d) void dev_sio_stop(struct dev *d) { - if (!sio_eof(d->sio.hdl) && !sio_stop(d->sio.hdl)) { + if (!sio_eof(d->sio.hdl) && !sio_flush(d->sio.hdl)) { if (log_level >= 1) { dev_log(d); log_puts(": failed to stop device\n"); diff --git a/usr.bin/sndiod/sock.c b/usr.bin/sndiod/sock.c index fcf97cf09fc..382fa6a6357 100644 --- a/usr.bin/sndiod/sock.c +++ b/usr.bin/sndiod/sock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sock.c,v 1.45 2021/11/01 14:43:25 ratchov Exp $ */ +/* $OpenBSD: sock.c,v 1.46 2022/04/29 08:30:48 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov * @@ -1186,7 +1186,7 @@ sock_execmsg(struct sock *f) f->ralign = s->round * s->mix.bpf; } } - slot_stop(s, 1); + slot_stop(s, AMSG_ISSET(m->u.stop.drain) ? m->u.stop.drain : 1); break; case AMSG_SETPAR: #ifdef DEBUG