From nobody Mon Aug 26 13:54:46 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4WsscQ2kSqz5SxwM; Mon, 26 Aug 2024 13:54:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4WsscQ2D7wz4dvj; Mon, 26 Aug 2024 13:54:46 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1724680486; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=8ddatbgwQXdQm+8Cprut7OB3yRbmncR6uBsF5OMS9eI=; b=R6HUDuRRkmtmDx2OGwwK1pw8JAM+k6bJXGMNvnBjYCjneAGAiax7SHPxbJxpiRvUkg/WRy BC6ZoN5nbqMkW/3mLay8UTVbRcacN1wVMgCt5NsJuL8H7f9lo2ICgg/E+XjXfkd4BAztQy znJqTn+y+GginC9oSYqq9jj/jrLC4gYUuJ21egGMLI3nOq4/oHvADUi5P118pD+sSNndiY h9hLS94IkzUgUcNAht5WZd1J2gOoV14C9op0ozI35IU9w9Ws0l2CfTUuR/SrJyeOnlBzNY wLxD5upFPiyroADprBz/URTEjtodYZEhND0yhN2SQ1V/UlcquWQVjYT4/1iBUA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1724680486; a=rsa-sha256; cv=none; b=MOZOEvCY8k9sVdr+iqZL3aHTUieOK4bu6rfNcgrBQnDtzxieVtrVE6pAeGLnQx8xbWfpWR eHyB21krApE+88Hk9pGdXh07A6h8oO4dqq3Wtp+qD60sRI6JEJ7Lm4JP4aCOpKh67GMPcb JDWQqN7rOBHhvs4yQ7hAIGVNnAOEE4JeOhcE3QNV/XlGAFJ+ttoHLaHCtBV9OROVGSqwUL yrK2azZuYMOK2XSb5MGmv0R9u50U4GWuGfQDw45kiPhtPEL8feWhs9xj6W7Q3g5wpFr2Az wy5KzEZw/KkWr4MkWDYLbF8KxitoTwi6ie67czhY/PNaCG+BbwEOATltmyxuLA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1724680486; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=8ddatbgwQXdQm+8Cprut7OB3yRbmncR6uBsF5OMS9eI=; b=OFY0cWv3SvUvCSD6S51edxTLPo+gIOSKot1ZY5nQGEDDyFMf7egJYgFzcldg1LOdkbrM7v BNsYnCkUz5gcBaXNeEs4SqWWwdL9EM91oB5yX0BQkQFDU1Fnu8DUTC6QOfXZBhmGLuT5KZ uscZPmKNrFYKEjYsX4Szsp0PgQUWCWSra18cREBR3W3kk+COg1fQ0MTrLAXiQfhceycNG9 SNLwCERFn944m5DTUB8N/CQKvACL9pM1Phh8L/llJw6/bs3Waz8ZBc2x1VMbwn3gHbPu7o CLpRfPCYR5TCbeC2O1IfJP4TSBqVCFvTNuJr5Ancm5WSj38UyvJ9IFRLQUKtdw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4WsscQ1rPfz17kd; Mon, 26 Aug 2024 13:54:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 47QDskQe017322; Mon, 26 Aug 2024 13:54:46 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 47QDsk8O017319; Mon, 26 Aug 2024 13:54:46 GMT (envelope-from git) Date: Mon, 26 Aug 2024 13:54:46 GMT Message-Id: <202408261354.47QDsk8O017319@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Christos Margiolis Subject: git: cf9d2fb18433 - stable/14 - mixer(8): Implement hot-swapping List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: christos X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: cf9d2fb184338b73c362b98bb8fadd2de9d94634 Auto-Submitted: auto-generated The branch stable/14 has been updated by christos: URL: https://cgit.FreeBSD.org/src/commit/?id=cf9d2fb184338b73c362b98bb8fadd2de9d94634 commit cf9d2fb184338b73c362b98bb8fadd2de9d94634 Author: Christos Margiolis AuthorDate: 2024-08-24 12:07:35 +0000 Commit: Christos Margiolis CommitDate: 2024-08-26 13:52:02 +0000 mixer(8): Implement hot-swapping Introduce a -V option, which can be used alongside -d (default unit change), in order to hot-swap devices (i.e switch to them on the fly without needing to restart the track), in case virtual_oss(8) exists and is running. Sponsored by: The FreeBSD Foundation MFC after: 2 days Reviewed by: dev_submerge.ch Differential Revision: https://reviews.freebsd.org/D46253 (cherry picked from commit 9aac27599acaffa21ff69c5be8a2d71d29cc3d6b) --- usr.sbin/mixer/mixer.8 | 75 +++++++++++++++++++++++++++++++++++++++++++--- usr.sbin/mixer/mixer.c | 81 +++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 145 insertions(+), 11 deletions(-) diff --git a/usr.sbin/mixer/mixer.8 b/usr.sbin/mixer/mixer.8 index 75c6a81e3a55..819d8ae73ab1 100644 --- a/usr.sbin/mixer/mixer.8 +++ b/usr.sbin/mixer/mixer.8 @@ -19,7 +19,7 @@ .\" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN .\" THE SOFTWARE. .\" -.Dd February 8, 2024 +.Dd August 14, 2024 .Dt MIXER 8 .Os .Sh NAME @@ -28,7 +28,7 @@ .Sh SYNOPSIS .Nm .Op Fl f Ar device -.Op Fl d Ar pcmN | N +.Op Fl d Ar pcmN | N Op Fl V Ar voss_device:mode .Op Fl os .Op Ar dev Ns Op Cm \&. Ns Ar control Ns Op Cm \&= Ns Ar value .Ar ... @@ -43,7 +43,7 @@ The utility is used to set and display soundcard mixer device controls. .Pp The options are as follows: -.Bl -tag -width "-d pcmN | N" +.Bl -tag -width "-V voss_device:mode" .It Fl a Print the values for all mixer devices available in the system .Pq see Sx FILES . @@ -54,6 +54,30 @@ where N is the unit number (e.g for pcm0, the unit number is 0). See .Sx EXAMPLES on how to list all available audio devices in the system. +.Pp +There is also the possibility of hot-swapping to the new default device if +.Xr virtual_oss 8 +exists in the system and is running, in which case the +.Fl V +option needs to be specified as well. +.Pp +Hot-swapping generally cannot happen with plain +.Xr sound 4 , +so the user has to restart the track in order to get sound coming out of the +new default device. +This is because applications usually open a device at the start of the track +and do not check for default device changes, in order to open the new device +mid-track. +.Xr virtual_oss 8 , +on the other hand, can do hot-swapping, because it creates a virtual device for +applications to open, and then does all the necessary routing and conversions +to the appropriate device(s). +.Pp +Note that hot-swapping will work only for applications that are using +.Xr virtual_oss 8 +devices, and not plain +.Xr sound 4 +ones. .It Fl f Ar device Open .Ar device @@ -66,6 +90,33 @@ Print mixer values in a format suitable for use inside scripts. The mixer's header (name, audio card name, ...) will not be printed. .It Fl s Print only the recording source(s) of the mixer device. +.It Fl V Ar voss_device:mode +Specify a +.Xr virtual_oss 8 +control device, as well as a mode (see below), in order to hot-swap devices. +This option is meant to only be used in combination with the +.Fl d +option. +.Pp +The available modes are as follows: +.Bl -column play +.It Sy Mode Ta Sy Action +.It all Ta Playback and recording +.It play Ta Playback +.It rec Ta Recording +.El +.Pp +The +.Pa mode +part is needed, so that +.Nm +will not accidentally hot-swap both the recording and playback device in +.Xr virtual_oss 8 , +if only one direction is to be hot-swapped. +.Pp +See +.Sx EXAMPLES +on how to use this option. .El .Pp The list of mixer devices that may be modified are: @@ -273,10 +324,26 @@ $ mixer -f /dev/mixer0 -o > info \&... $ mixer -f /dev/mixer0 `cat info` .Ed +.Pp +Suppose +.Xr virtual_oss 8 +is running with +.Pa /dev/vdsp.ctl +as its control device, and +.Pa pcm0 +as the playback device. +Change the default device to +.Pa pcm1 , +and hot-swap to it for both recording and playback in +.Xr virtual_oss 8 : +.Bd -literal -offset indent +$ mixer -d pcm1 -V /dev/vdsp.ctl:all +.Ed .Sh SEE ALSO .Xr mixer 3 , .Xr sound 4 , -.Xr sysctl 8 +.Xr sysctl 8 , +.Xr virtual_oss 8 .Sh HISTORY The .Nm diff --git a/usr.sbin/mixer/mixer.c b/usr.sbin/mixer/mixer.c index 109d3ad09bc5..468130ddaa88 100644 --- a/usr.sbin/mixer/mixer.c +++ b/usr.sbin/mixer/mixer.c @@ -20,6 +20,9 @@ * THE SOFTWARE. */ +#include +#include + #include #include #include @@ -40,7 +43,7 @@ static void printall(struct mixer *, int); static void printminfo(struct mixer *, int); static void printdev(struct mixer *, int); static void printrecsrc(struct mixer *, int); /* XXX: change name */ -static int set_dunit(struct mixer *, int); +static int set_dunit(struct mixer *, int, char *); /* Control handlers */ static int mod_volume(struct mix_dev *, void *); static int mod_mute(struct mix_dev *, void *); @@ -54,13 +57,13 @@ main(int argc, char *argv[]) { struct mixer *m; mix_ctl_t *cp; - char *name = NULL, buf[NAME_MAX]; + char *name = NULL, buf[NAME_MAX], *vctl = NULL; char *p, *q, *devstr, *ctlstr, *valstr = NULL; int dunit, i, n, pall = 1, shorthand; int aflag = 0, dflag = 0, oflag = 0, sflag = 0; int ch; - while ((ch = getopt(argc, argv, "ad:f:hos")) != -1) { + while ((ch = getopt(argc, argv, "ad:f:hosV:")) != -1) { switch (ch) { case 'a': aflag = 1; @@ -83,6 +86,9 @@ main(int argc, char *argv[]) case 's': sflag = 1; break; + case 'V': + vctl = optarg; + break; case 'h': /* FALLTHROUGH */ case '?': default: @@ -119,7 +125,7 @@ main(int argc, char *argv[]) initctls(m); if (dflag) { - if (set_dunit(m, dunit) < 0) + if (set_dunit(m, dunit, vctl) < 0) goto parse; else { /* @@ -209,7 +215,8 @@ next: static void __dead2 usage(void) { - fprintf(stderr, "usage: %1$s [-f device] [-d pcmN | N] [-os] [dev[.control[=value]]] ...\n" + fprintf(stderr, "usage: %1$s [-f device] [-d pcmN | N " + "[-V voss_device:mode]] [-os] [dev[.control[=value]]] ...\n" " %1$s [-os] -a\n" " %1$s -h\n", getprogname()); exit(1); @@ -322,9 +329,32 @@ printrecsrc(struct mixer *m, int oflag) } static int -set_dunit(struct mixer *m, int dunit) +set_dunit(struct mixer *m, int dunit, char *vctl) { - int n; + const char *opt; + char *dev, *mode; + char buf[32]; + size_t size; + int n, rc; + + /* + * Issue warning in case of hw.snd.basename_clone being unset. Omit the + * check and warning if the -V flag is used, since the user is most + * likely to be aware of this, and the warning might be confusing. + */ + if (vctl == NULL) { + size = sizeof(int); + if (sysctlbyname("hw.snd.basename_clone", &n, &size, + NULL, 0) < 0) { + warn("hw.snd.basename_clone failed"); + return (-1); + } + if (n == 0) { + warnx("warning: hw.snd.basename_clone not set. " + "/dev/dsp is managed externally and does not " + "change with the default unit change here."); + } + } if ((n = mixer_get_dunit()) < 0) { warn("cannot get default unit"); @@ -336,6 +366,43 @@ set_dunit(struct mixer *m, int dunit) } printf("default_unit: %d -> %d\n", n, dunit); + /* Hot-swap in case virtual_oss exists and is running. */ + if (vctl != NULL) { + dev = strsep(&vctl, ":"); + mode = vctl; + if (dev == NULL || mode == NULL) { + warnx("voss_device:mode tuple incomplete"); + return (-1); + } + if (strcmp(mode, "all") == 0) + opt = "-f"; + else if (strcmp(mode, "play") == 0) + opt = "-P"; + else if (strcmp(mode, "rec") == 0) + opt = "-R"; + else { + warnx("please use one of the following modes: " + "all, play, rec"); + return (-1); + } + snprintf(buf, sizeof(buf), "/dev/dsp%d", dunit); + switch (fork()) { + case -1: + warn("fork"); + break; + case 0: + rc = execl("/usr/local/sbin/virtual_oss_cmd", + "virtual_oss_cmd", dev, opt, buf, NULL); + if (rc < 0) + warn("virtual_oss_cmd"); + _exit(0); + default: + if (wait(NULL) < 0) + warn("wait"); + break; + } + } + return (0); }