diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2013-05-03 21:08:42 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2013-05-03 21:08:42 +0400 |
commit | 1058def8e7827e56ce4a70afb4aeacb5dc44148f (patch) | |
tree | 4495d23e7b54ab5700e3839081e797c1eafe0db9 /cmd/vmixctl | |
download | oss4-upstream.tar.gz |
Imported Upstream version 4.2-build2006upstream/4.2-build2006upstream
Diffstat (limited to 'cmd/vmixctl')
-rw-r--r-- | cmd/vmixctl/.config | 2 | ||||
-rw-r--r-- | cmd/vmixctl/vmixctl.c | 280 | ||||
-rw-r--r-- | cmd/vmixctl/vmixctl.man | 111 |
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 |