/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" /* * audio_clean - Clear any residual data that may be residing in the in the * audio device driver or chip. * * Usage: audio_clean [-Iisf] device_name * * Note: The same operation is performed for any of the "ifs" flags. * The "I" flag is a silent form of "i". Support for the flags * is provided so that the framework is place if added * functionality is required. * * Note: The AUDIO_SETINFO ioctl is used instead of the low level * AUDIOSETREG command which is used to perform low level * operations on the device. If a process had previously used * AUDIOSETREG to monkey with the device, then the driver would * have reset the chip when the process performed a close, * so this can just clear the info structure. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef TEXT_DOMAIN #define TEXT_DOMAIN "SUNW_OST_OSCMD" #endif #ifdef DEBUG static void print_info(audio_info_t *); static void print_prinfo(audio_prinfo_t *); #endif /* DEBUG */ static void usage(char *prog) { (void) fprintf(stderr, "%s%s", prog, gettext(" : usage:[-I|-s|-f|-i] device\n")); } int main(int argc, char **argv) { int err = 0; int Audio_fd; int forced = 0; /* Command line options */ int initial = 0; int standard = 0; int verbose = 1; /* default is to be verbose */ int c; char *prog, *devname, *devpath; devmap_t *dm; struct stat st; audio_info_t info; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); prog = argv[0]; /* save program initiation name */ /* * Parse arguments. Currently i, s and f all do the * the same thing. */ while ((c = getopt(argc, argv, "Iifs")) != -1) { switch (c) { case 'I': verbose = 0; initial++; if (standard || forced) err++; break; case 'i': initial++; if (standard || forced) err++; break; case 's': standard++; if (initial || forced) err++; break; case 'f': forced++; if (initial || standard) err++; break; case '?': err++; break; default: err++; break; } if (err) { if (verbose) usage(prog); exit(1); } } if ((argc - optind) != 1) { if (verbose) usage(prog); exit(1); } else { devname = argv[optind]; } setdmapent(); if ((dm = getdmapnam(devname)) == NULL) { enddmapent(); if (verbose) (void) fprintf(stderr, "%s%s", devname, gettext(" : No such allocatable device\n")); exit(1); } enddmapent(); if (dm->dmap_devarray == NULL || dm->dmap_devarray[0] == NULL) { if (verbose) (void) fprintf(stderr, "%s%s", devname, gettext(" : No such allocatable device\n")); exit(1); } devpath = strdup(dm->dmap_devarray[0]); freedmapent(dm); /* * Validate and open the audio device */ err = stat(devpath, &st); if (err < 0) { if (verbose) { (void) fprintf(stderr, gettext("%s: cannot stat "), prog); perror("audio_clean"); } exit(1); } if (!S_ISCHR(st.st_mode)) { if (verbose) (void) fprintf(stderr, gettext("%s: %s is not an audio device\n"), prog, devpath); exit(1); } /* * Since the device /dev/audio can suspend if someone else is * using it we check to see if we're going to hang before we * do anything. */ Audio_fd = open(devpath, O_WRONLY | O_NDELAY); if ((Audio_fd < 0) && (errno == EBUSY)) { if (verbose) (void) fprintf(stderr, gettext("%s: waiting for %s..."), prog, devpath); exit(0); } else if (Audio_fd < 0) { if (verbose) { (void) fprintf(stderr, gettext("%s: error opening "), prog); perror(devpath); } exit(1); } #ifdef DEBUG /* * Read the audio_info structure. */ if (ioctl(Audio_fd, AUDIO_GETINFO, &info) != 0) { perror("Ioctl AUDIO_GETINFO error"); (void) close(Audio_fd); exit(1); } print_info(&info); #endif /* DEBUG */ /* LINTED */ AUDIO_INITINFO(&info); /* clear audit info structure */ if (ioctl(Audio_fd, AUDIO_SETINFO, &info) != 0) { if (verbose) perror(gettext("Ioctl AUDIO_SETINFO error")); (void) close(Audio_fd); exit(1); } #ifdef DEBUG if (ioctl(Audio_fd, AUDIO_GETINFO, &info) != 0) { perror("Ioctl AUDIO_GETINFO-2 error"); (void) close(Audio_fd); exit(1); } print_info(&info); #endif /* DEBUG */ return (0); } #ifdef DEBUG void print_info(audio_info_t *info) { print_prinfo(&info->play); print_prinfo(&info->record); (void) printf("monitor_gain %d\n", info->monitor_gain); (void) fflush(stdout); } void print_prinfo(audio_prinfo_t *prinfo) { /* The following values decribe audio data encoding: */ (void) printf("sample_rate %d\n", prinfo->sample_rate); (void) printf("channels %d\n", prinfo->channels); (void) printf("precision %d\n", prinfo->precision); (void) printf("encoding %d\n", prinfo->encoding); /* The following values control audio device configuration */ (void) printf("gain %d\n", prinfo->gain); (void) printf("port %d\n", prinfo->port); (void) printf("avail_ports %d\n", prinfo->avail_ports); (void) printf("mod_ports %d\n", prinfo->mod_ports); /* These are Reserved for future use, but we clear them */ (void) printf("_xxx %d\n", prinfo->_xxx); (void) printf("buffer_size %d\n", prinfo->buffer_size); /* The following values describe driver state */ (void) printf("samples %d\n", prinfo->samples); (void) printf("eof %d\n", prinfo->eof); (void) printf("pause %d\n", prinfo->pause); (void) printf("error %d\n", prinfo->error); (void) printf("waiting %d\n", prinfo->waiting); (void) printf("balance %d\n", prinfo->balance); /* The following values are read-only state flags */ (void) printf("open %d\n", prinfo->open); (void) printf("active %d\n", prinfo->active); } #endif /* DEBUG */