📄 common.c
字号:
return EFINDDEVICE; return 0;}int MixerStatus(void){/* Get status of the mixer. Global: mixer_fd = mixer file descriptor reference number Bit masks indicating: devmask = devices with adjustable levels recmask = valid input devices recsrc = devices currently selected for input stereodevs = stereo devices *//*"If an error has occurred, a value of -1 is returned and errno is set to indicate the error."--ioctl(2), FreeBSD System Calls Manual, Joseph Koshy"On success, zero is returned. On error, -1 is returned, and errno is set appropriately."--ioctl(2), Linux Programmer's Manual, Rik Faith and Eric S. RaymondRobert Siemer says that on his Linux system the SOUND_MIXER_READ_DEVMASK ioctl returns a large positive value.*/ if (SOUND_IOCTL(mixer_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) return EREADDEV; if (SOUND_IOCTL(mixer_fd, SOUND_MIXER_READ_RECMASK, &recmask) == -1) return EREADRECMASK; ErrorExitWarn(ReadRecSrc(), 'e'); if (SOUND_IOCTL(mixer_fd, SOUND_MIXER_READ_STEREODEVS, &stereodevs) == -1) return EREADSTEREO; return 0;}int WriteLevel(int device, int leftright){ if (SOUND_IOCTL(mixer_fd, MIXER_WRITE(device), &leftright) == -1) return EWRITEMIX; return 0;}int ReadLevel(int device, int *leftright){ if (SOUND_IOCTL(mixer_fd, MIXER_READ(device), leftright) == -1) return EREADMIX; return 0;}int WriteRecSrc(void){ if (SOUND_IOCTL(mixer_fd, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1) return EWRITERECSRC; return 0;}int ReadRecSrc(void){ if (SOUND_IOCTL(mixer_fd, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) return EREADRECSRC; return 0;}#if 0int ReadWriteMixer(int device, char *rw, int *left, int *right, char *rp){/* Read or write settings. * Global: * * mixer_fd = mixer file descriptor reference number * * Bit masks indicating: * * devmask = devices with adjustable levels * recmask = valid input devices * recsrc = devices currently selected for input * stereodevs = stereo devices * * Input: * * device = index into the array of mixer devices * rw = r - read : w - write * left = left channel setting * right = right channel setting * rp = r - record : p - play * * * Output: * * left = left channel setting * right = right channel setting * rp = r - record : p - play * * Return: * * success: = 0 * failure: = 7 SOUND_MIXER_WRITE_RECSRC * failure: = 8 MIXER_READ * failure: = 9 MIXER_WRITE * failure: = 10 mixer not open */ int rightleft, result; if (mixer_fd == -1) /* We haven't opened the mixer. */ return ENOTOPEN; result = MixerStatus(); if (result) return result;/* Is the given device index valid? */ if (!((1 << device) & (devmask | recmask))) return 0;/* Read settings. */ if (((1 << device) & devmask) & (*rw == 'r') { ErrorExitWarn(ReadLevel(device, &rightleft), 'e');/* Unpack left and right settings. */ if ((1 << device) & stereodevs) { *right = ((rightleft >> 8) & 0xFF); *left = rightleft & 0xFF; } else { *right = ((rightleft >> 8) & 0xFF); *left = rightleft & 0xFF; }/* Can the current device be a recording source? */ if ((1 << device) & recmask) { *rp = (1 << device) & recsrc ? 'R' : 'P'; } else { *rp = '\0'; } } else {/* "But it's got 11, so it *must* be louder." */ *left = (*left > MAXLEVEL) ? MAXLEVEL : *left; *left = (*left < 0) ? 0 : *left; *right = (*right > MAXLEVEL) ? MAXLEVEL : *right; *right = (*right < 0) ? 0 : *right;/* Pack left and right settings for writing. */ rightleft = *left + (*right << 8);/* Write settings. */ ErrorExitWarn(WriteLevel(device, rightleft), 'e'); }/* Is the current device capable of being a recording source? */ if ((1 << device) & recmask) { *rp = *rp & 0xDF; if (*rp == 'R') { recsrc = recsrc | (1 << device); } else { recsrc = recsrc & ~(1 << device); *rp = 'P'; }/* Set recording or playing mode. */ ErrorExitWarn(WriteRecSrc(), 'e'); } else { *rp = '\0'; } return 0;}#endif /* 0 */int CountChannels(int limit){/* How many mixing channels are less than limit? */ int ii, y = 0; for (ii = 0; ii < limit; ii++) if ((devmask | recmask) & (1 << ii)) y++; return y;}FILE *CheckAndOpen(const char *filename, const char *mode){/* Check whether *filename is a directory, and if not, call fopen on it. CheckAndOpen() is meant to be a drop-in replacement for fopen(). */ struct stat s; int result; /* fopen will fail if mode=='w' and filename is a directory, so we * only need to check the mode=='r' case */ if (*mode == 'r') { result = stat(filename, &s); if (result != 0) return NULL; /* stat() failed */ if (S_ISDIR(s.st_mode)) return NULL; /* is a directory, so bail */ } return fopen(filename, mode);}FILE *OpenDefaultFile(char *mode){/* Open the settings file for reading or writing. Try first ${HOME}/.AUMIXRC, then AUMIXRC_PATH/AUMIXRC; become an error generator if neither can be opened. Input: mode should be either 'r' (read) or 'w' (write) Return: Success: pointer to the default settings file structure Failure: NULL */ FILE *setfile; char *home; char filename[PATH_MAX]; if (save_filename == NULL) { home = getenv("HOME"); if ((strlen(home) + strlen(AUMIXRC) + 2) < PATH_MAX) { sprintf(filename, "%s/.%s", home, AUMIXRC); setfile = CheckAndOpen(filename, mode); } if (setfile == NULL) { if ((strlen(AUMIXRC_PATH) + strlen(AUMIXRC) + 1) < PATH_MAX) { sprintf(filename, "%s/%s", AUMIXRC_PATH, AUMIXRC); setfile = CheckAndOpen(filename, mode); } } if (setfile == NULL) { return NULL; } } else setfile = CheckAndOpen(save_filename, mode); return setfile;}int SetShowNoninter(int dev){/* Change or display settings from the command line. */ char *devstr, dest; int change = 0, tmp, left, right; /* Increase or decrease levels, optionally by a number. */ if (!strncmp(optarg, "+", 1) || !strncmp(optarg, "-", 1)) { ErrorExitWarn(ReadLevel(dev, &tmp), 'e'); right = tmp >> 8; /* I'll take the high byte, */ left = tmp & 0xFF; /* and you take the low byte. */ strncpy(&dest, (optarg + 1), 3); change = 1; /* For compatibility with versions 1.15 to 1.17, assume one if no number was given. */ if (atoi(&dest)) change = atoi(&dest); if (*optarg == '+') { /* increase */ right += change; left += change; right = (right > MAXLEVEL) ? MAXLEVEL : right; left = (left > MAXLEVEL) ? MAXLEVEL : left; } else { /* decrease */ left -= change; right -= change; left = (left < 0) ? 0 : left; right = (right < 0) ? 0 : right; } tmp = left + (right << 8); ErrorExitWarn(WriteLevel(dev, tmp), 'e'); /* Try to write new settings to the mixer. */ return 0; } if ((*optarg == 'R') || (*optarg == 'P')) { if ((1 << dev) & recmask) { recsrc = (*optarg == 'R') ? recsrc | (1 << dev) : recsrc & ~(1 << dev); ErrorExitWarn(WriteRecSrc(), 'e'); } return 0; } if ((*optarg == 'q') || (*optarg == ' ')) { devstr = dev_name[dev]; ErrorExitWarn(ReadLevel(dev, &tmp), 'e'); printf("%s %i, %i", dev_name[dev], (tmp & 0xFF), ((tmp >> 8) & 0xFF)); if ((1 << (dev)) & recmask) { ErrorExitWarn(ReadRecSrc(), 'e'); printf(", %c", ((1 << dev) & recsrc ? 'R' : 'P')); } printf("\n"); } else { tmp = atoi(optarg); tmp = (tmp > MAXLEVEL) ? MAXLEVEL : tmp; tmp = (tmp < 0) ? 0 : 257 * tmp; ErrorExitWarn(WriteLevel(dev, tmp), 'e'); } return 0;}void Usage(int status){ FILE *fp;/* These declarations are for embedding the copyright and version information in the binary for display by utilities such as what(1). They needn't be translated. */ static char version[] = "@(#) aumix " VERSION "\n"; static char copyright[] = "@(#) copyright (c) 1993, 1996-2000 the authors--see AUTHORS file\n"; fp = (status == EXIT_SUCCESS) ? stdout : stderr; fprintf(fp, LOCAL_TEXT("aumix %s usage: aumix [-<channel option>[[+|-][<amount>]]|<level>|\nR[ecord]|P[lay]|q[uery]]"), VERSION);#if defined(HAVE_CURSES) || defined(HAVE_GTK) || defined(HAVE_GTK1) fprintf(fp, LOCAL_TEXT(" [-dhILqS]"));#else fprintf(fp, LOCAL_TEXT(" [-dhLqS]"));#endif#if defined(HAVE_CURSES) fprintf(fp, LOCAL_TEXT(" [-C <color scheme file>]"));#endif fprintf(fp, LOCAL_TEXT(" [-f <rc file>]")); fprintf(fp, "\n\n"); fprintf(fp, LOCAL_TEXT("\channel options:\n\ v: main volume x: mix monitor\n\ b: bass W: PCM 2\n\ t: treble r: record\n\ s: synthesizer i: input gain\n\ w: PCM o: output gain\n\ p: PC speaker 1: line 1\n\ l: line 2: line 2\n\ m: microphone 3: line 3\n\ c: CD\n\n\other options:\n"));#ifdef HAVE_CURSES fprintf(fp, LOCAL_TEXT("\ C: specify color scheme\n"));#endif /* HAVE_CURSES */ fprintf(fp, LOCAL_TEXT("\ d: adjust a device besides /dev/mixer\n\ f: specify file for saving and loading settings (defaults to\n\ ~/.aumixrc or /etc/aumixrc)\n\ h: this helpful message\n"));#if defined(HAVE_CURSES) || defined(HAVE_GTK) || defined(HAVE_GTK1) fprintf(fp, LOCAL_TEXT("\ I: start in interactive mode after doing non-interactive functions\n"));#endif /* HAVE_CURSES || HAVE_GTK || HAVE_GTK1 */ fprintf(fp, LOCAL_TEXT("\ L: load settings\n\ q: query all channels and print their settings\n\ S: save settings\n")); exit(status);}/* Initialize I18N. The initialization amounts to invoking setlocale(), bindtextdomain() and textdomain(). Does nothing if NLS is disabled or missing. */void I18nInitialize(void){ /* * If HAVE_NLS is defined, assume the existence of the three functions invoked here. */#ifdef HAVE_NLS /* Set the current locale. */ setlocale(LC_ALL, ""); /* Set the text message domain. */ bindtextdomain((char *) PACKAGE, LOCALEDIR); textdomain((char *) PACKAGE);#endif /* HAVE_NLS */}#ifdef HAVE_ALSA/* Unmuting "hardware mute" in ALSA driver. Currently unmuting is done only for the first sound system. Although it could be done without the library, this code requires alsa-lib. */void AlsaUnmute(void){ int channel; snd_mixer_channel_t cdata = {0}; static snd_mixer_info_t mixer_info = {0}; static int card_id = 0; static int mixer_id = 0; static void *mixer_handle; static struct snd_ctl_hw_info hw_info; void *ctl_handle; if (!snd_mixer_open(&mixer_handle, card_id, mixer_id)) { snd_mixer_info(mixer_handle, &mixer_info); channel = snd_mixer_channels(mixer_handle); while (channel >= 0) { snd_mixer_channel_read(mixer_handle, channel, &cdata);/* Turn off hardware mute for all channels. */ cdata.flags &= ~SND_MIXER_FLG_MUTE_LEFT; cdata.flags &= ~SND_MIXER_FLG_MUTE_RIGHT; snd_mixer_channel_write(mixer_handle, channel, &cdata); --channel; } snd_mixer_close(mixer_handle); }}#endif /* HAVE_ALSA */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -