summaryrefslogtreecommitdiff
path: root/cmd/vmixctl
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2013-05-03 21:08:42 +0400
committerIgor Pashev <pashev.igor@gmail.com>2013-05-03 21:08:42 +0400
commit1058def8e7827e56ce4a70afb4aeacb5dc44148f (patch)
tree4495d23e7b54ab5700e3839081e797c1eafe0db9 /cmd/vmixctl
downloadoss4-upstream.tar.gz
Imported Upstream version 4.2-build2006upstream/4.2-build2006upstream
Diffstat (limited to 'cmd/vmixctl')
-rw-r--r--cmd/vmixctl/.config2
-rw-r--r--cmd/vmixctl/vmixctl.c280
-rw-r--r--cmd/vmixctl/vmixctl.man111
3 files changed, 393 insertions, 0 deletions
diff --git a/cmd/vmixctl/.config b/cmd/vmixctl/.config
new file mode 100644
index 0000000..2ab03c2
--- /dev/null
+++ b/cmd/vmixctl/.config
@@ -0,0 +1,2 @@
+mode=sbin
+forgetos=VxWorks
diff --git a/cmd/vmixctl/vmixctl.c b/cmd/vmixctl/vmixctl.c
new file mode 100644
index 0000000..cb487c5
--- /dev/null
+++ b/cmd/vmixctl/vmixctl.c
@@ -0,0 +1,280 @@
+/*
+ * Purpose: Utility to control the vmix subsystem of Open Sound System
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <oss_config.h>
+#include <sys/ioctl.h>
+
+char *cmdname=NULL;
+
+#ifndef CONFIG_OSS_VMIX
+int
+main(int argc, char *argv[])
+{
+ fprintf (stderr, "%s: Virtual mixer is not included in this version of OSS\n", argv[0]);
+ exit(1);
+}
+#else
+
+static void
+usage(void)
+{
+ fprintf (stdout, "Usage:\n");
+ fprintf (stdout, "%s attach [attach_options...] devname\n", cmdname);
+ fprintf (stdout, "%s attach [attach_options...] devname inputdev\n", cmdname);
+ fprintf (stdout, "%s detach devname\n", cmdname);
+ fprintf (stdout, "%s rate devname samplerate\n", cmdname);
+ fprintf (stdout, "%s remap devname channels\n", cmdname);
+ fprintf (stdout, "\n");
+ fprintf (stdout, "Use ossinfo -a to find out the devname and inputdev parameters\n");
+ fprintf (stdout, "Use ossinfo -a -v2 to find out a suitable sample rate.\n");
+ fprintf (stdout, "\n");
+ fprintf (stdout, "attach_options:\n");
+ fprintf (stdout, "\n");
+ fprintf (stdout, "\t-r\tDisable recording\n");
+ fprintf (stdout, "\t-p\tDo not preallocate client engines\n");
+ fprintf (stdout, "\t-M\tUse more fragments\n");
+ fprintf (stdout, "\t-V\tMake clients visible by creating device files for them.\n");
+ fprintf (stdout, "\t-c<N>\tPrecreate <N> client engines (see -p).\n");
+
+ exit(-1);
+}
+
+static int
+find_audiodev(char *fname, int mode, int *fd_)
+{
+ int fd;
+ oss_audioinfo ai;
+
+ if ((fd=*fd_=open(fname, mode | O_EXCL, 0))==-1)
+ {
+ perror(fname);
+ exit(-1);
+ }
+
+ ai.dev=-1;
+ if (ioctl(fd, SNDCTL_ENGINEINFO, &ai)==-1)
+ {
+ perror("SNDCTL_ENGINEINFO");
+ fprintf (stderr, "Cannot get engine info for %s\n", fname);
+ exit(-1);
+ }
+
+ return ai.dev;
+}
+
+static int
+vmix_attach(int argc, char **argv)
+{
+ int masterfd, inputfd=-1;
+ int masterdev, inputdev=-1;
+ int c, n;
+ int relink_devices = 0;
+ extern int optind;
+ extern char * optarg;
+
+ vmixctl_attach_t att={0};
+
+ att.attach_flags = VMIX_INSTALL_MANUAL;
+/*
+ * Simple command line switch handling.
+ */
+ argv++;argc--; /* Skip the initial command ("attach") */
+
+ while ((c = getopt (argc, argv, "MVc:pr")) != EOF)
+ {
+ switch (c)
+ {
+ case 'r': /* No input */
+ att.attach_flags |= VMIX_INSTALL_NOINPUT;
+ break;
+
+ case 'p': /* No client engine preallocation */
+ att.attach_flags |= VMIX_INSTALL_NOPREALLOC;
+ break;
+
+ case 'V': /* Allocate private device files for all clients */
+ att.attach_flags |= VMIX_INSTALL_VISIBLE;
+ relink_devices=1;
+ break;
+
+ case 'M': /* Use more fragments */
+ att.attach_flags |= VMIX_MULTIFRAG;
+ break;
+
+ case 'c': /* Force prealloc of N client devices */
+ n = atoi(optarg);
+ if (n>255)n=255;
+ if (n<0)n=0;
+ att.attach_flags |= n;
+ break;
+
+ default:
+ usage();
+ }
+ }
+
+ if (optind >= argc)
+ usage();
+
+ masterdev=find_audiodev(argv[optind], O_WRONLY, &masterfd);
+
+ optind++;
+
+ if (optind<argc)
+ inputdev=find_audiodev(argv[optind], O_RDONLY, &inputfd);
+
+ att.masterdev=masterdev;
+ att.inputdev=inputdev;
+
+ if (ioctl(masterfd, VMIXCTL_ATTACH, &att)==-1)
+ {
+ perror("VMIXCTL_ATTACH");
+ exit(-1);
+ }
+
+ fprintf (stdout, "Virtual mixer attached to device.\n");
+
+ if (relink_devices)
+ {
+ n = system("ossdetect -d");
+ n = system("ossdevlinks");
+ }
+
+ return 0;
+}
+
+static int
+vmix_detach(int argc, char **argv)
+{
+ int masterfd;
+ int masterdev;
+
+ vmixctl_attach_t att;
+
+ masterdev=find_audiodev(argv[2], O_WRONLY, &masterfd);
+
+ att.masterdev=masterdev;
+ att.inputdev=-1;
+
+ if (ioctl(masterfd, VMIXCTL_DETACH, &att)==-1)
+ {
+ perror("VMIXCTL_DETACH");
+ exit(-1);
+ }
+
+ fprintf (stdout, "Virtual mixer detached from device.\n");
+
+ return 0;
+}
+
+static int
+vmix_rate(int argc, char **argv)
+{
+ int masterfd;
+ int masterdev;
+
+ vmixctl_rate_t rate;
+
+ if (argc<4)
+ {
+ usage ();
+ }
+
+ masterdev=find_audiodev(argv[2], O_WRONLY, &masterfd);
+
+ rate.masterdev=masterdev;
+ rate.rate=atoi(argv[3]);
+
+ if (ioctl(masterfd, VMIXCTL_RATE, &rate)==-1)
+ {
+ perror("VMIXCTL_RATE");
+ exit(-1);
+ }
+
+ fprintf (stdout, "Virtual mixer rate change requested.\n");
+
+ return 0;
+}
+
+static int
+vmix_remap(int argc, char **argv)
+{
+ int i;
+ int masterfd;
+ int masterdev;
+
+ vmixctl_map_t map;
+
+ if (argc<4)
+ {
+ usage ();
+ }
+
+ masterdev=find_audiodev(argv[2], O_WRONLY, &masterfd);
+ memset (&map, 0, sizeof (map));
+
+ map.masterdev=masterdev;
+ map.map[0]=atoi(argv[3]);
+
+ for (i=4; i<argc; i++)
+ {
+ map.map[i-3] = atoi(argv[i]);
+ }
+
+ if (ioctl(masterfd, VMIXCTL_REMAP, &map)==-1)
+ {
+ perror("VMIXCTL_REMAP");
+ exit(-1);
+ }
+
+ fprintf (stdout, "Virtual mixer map change requested.\n");
+
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ cmdname=argv[0];
+
+ if (argc < 3)
+ {
+ usage ();
+ }
+
+ if (strcmp(argv[1], "attach")==0)
+ exit(vmix_attach(argc, argv));
+
+ if (strcmp(argv[1], "detach")==0)
+ exit(vmix_detach(argc, argv));
+
+ if (strcmp(argv[1], "rate")==0)
+ exit(vmix_rate(argc, argv));
+
+ if (strcmp(argv[1], "remap")==0)
+ exit(vmix_remap(argc, argv));
+
+ usage();
+ exit(0);
+}
+#endif
diff --git a/cmd/vmixctl/vmixctl.man b/cmd/vmixctl/vmixctl.man
new file mode 100644
index 0000000..c7ac50e
--- /dev/null
+++ b/cmd/vmixctl/vmixctl.man
@@ -0,0 +1,111 @@
+NAME
+vmixctl - Open Sound System utility to control the vmix subsystem.
+
+SYNOPSIS
+o vmixctl attach [attach_options...] audiodev [inputdev]
+o vmixctl detach [attach_options...] audiodev
+o vmixctl rate audiodev samplerate
+o vmixctl remap audiodev channels
+
+DESCRIPTION
+The vmixctl program can be used to attach or detach the virtual mixer subsystem
+(vmix) to/from audio devices. In addition it can be used to control vmix
+related parameters such as the sampling rate to be used with the device.
+
+By default most OSS drivers will attach virtual mixer to the primary audio device
+of the sound card (or motherboard audio chip) when the device is attached.
+However possible secondary audio devices (engines) will not have vmix
+attached by default. In additional professional audio devices will be
+attached without vmix because mixing may cause some unwanted distortion
+to the signal.
+
+ATTACHING VMIX TO AN AUDIO DEVICE
+There are two forms of vmixctl attach command:
+
+o vmixctl attach audiodev
+This alternative is to be used with devices that support only output or
+have a single audio device file that supports full duplex.
+o vmixctl attach audiodev inputdev
+The second form is to be used with devices that have separate output and
+input device files. The "audiodev" parameter defines the output device and
+the "inputdev" parameter is the device file to be used for input direction.
+Note that both device files must belong to the same "physical" sound card.
+In some cases it might be possible to use one sound card for playback and
+another for recording. However this configuration is not supported and the
+result may not be functional.
+
+To find out the right device file names (audiodev and inputdev) you can use
+the "ossinfo -a" command.
+
+ ATTACH OPTIONS
+o -r Disable recording functionality. By default vmix will support
+ recording if the master device(s) support it.
+o -p Do not preallocate client engines. By default vmix will
+ preallocate first 4 (out of 8) client engines when attaching
+ to the device. The remaining engines will be allocated
+ on-demand if there are more concurrent applications that
+ use the device.
+o -M Make vmix use more fragments.
+o -V Make client devices visible (have private device nodes under /dev).
+o -c <n> Preallocate <n> client engines instead of 4. However -p
+ option makes this option ineffective.
+
+ EXAMPLES
+o vmixctl attach /dev/oss/oss_envy240/pcm0
+o vmixctl attach /dev/oss/oss_envy240/pcm0 /dev/oss/oss_envy240/pcmin0
+
+SETTING THE SAMPLING RATE USED BY VMIX
+The virtual mixer subsystem will set the physical audio devce(s) to use
+fixed sampling rate that is 48000 Hz by default. It is possible to use
+"vmixctl rate audiodev" to switch vmix to use some different rate with this
+device (pair). You should use "ossinfo -a -v2" to verify that the sampling rate
+is actually supported by the device. Otherwise the actual device may enforce
+vmix to use the nearest supported rate (or some default rate).
+
+The "audiodev" parameter is the device file name (see ossinfo -a) that is
+used for playback. The input device name doesn't need to be specified.
+
+Note that some professional audio devices may be locked to external sampling
+rate or some fixed rate (defined in ossmix/ossxmis). In such case the rate is
+not changeable by vmixctl.
+
+ EXAMPLE
+o vmixctl rate /dev/oss/oss_envy240/pcm0 44100
+
+CHANGING THE VMIX CHANNEL MAP
+The vmix subsystem can remap channels, so that all output sent to a channel via
+vmix will end up being played on a different channel. The syntax uses a list of
+channels, where typically 0=default, 1=left, 2=right, 3=center, 4=lfe,
+5=left surround, 6=right surround, 7=left rear and 8=right rear.
+Note that vmix-channels should be set first to Multich if vmix is to recognize
+the extra channels.
+
+ EXAMPLES
+o vmixctl remap /dev/dsp 2 1 #switch left and right
+o vmixctl remap /dev/dsp 0 0 0 0 6 5 #switch left and right surround
+
+DETACHING VMIX FROM AN AUDIO DEVICE
+It is possible to detach vmix from an audio device if it causes problems
+with applications by using "vmix detach audiodev".
+
+It is not possible to detach and (re)attach vmix to the same device more
+than few times. Use the vmix-enable setting in the control panel
+(ossxmix or ossmix) to disable/re-enable vmix if you need to do it
+repeatedly. Use vmix detach only if you need to attach virtual mixer using
+different parameters.
+
+ EXAMPLE
+o vmix detach /dev/oss/oss_envy240/pcm0
+
+POSSIBLE BUGS
+o The control panel elements related with vmix are not removed from the
+ mixer API when vmix is detached. This may be somehow confusing.
+
+SEE ALSO
+soundoff(1), soundon(1), ossmix(1), ossxmix(1)
+
+FILES
+/usr/sbin/vmixct
+
+AUTHOR
+4Front Technologies