/* ** mix.c - Command-line driven volume control for Linux. ** Copyright (C) 2003 Ryan McCabe ** ** xmms provides a means to control it (pause, stop, play, fwd, back, etc.) ** via the command line. I have key bindings set in my window manager to do ** these things. It doesn't let you adjust the volume via the command line ** interface. I'd like to be able to do that with window manager key binds. ** Hence, this program. ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License, version 2, ** as published by the Free Software Foundation. */ #include #include #include #include #include #include #include int open_mixer(void) { return (open("/dev/mixer", O_RDWR | O_NONBLOCK)); } int get_level(int fd, int device) { int level = -1; if (ioctl(fd, MIXER_READ(device), &level) != 0) return (-1); return (level / 257); } int set_level(int fd, int device, int level) { if (level > 100) level = 100; else if (level < 0) level = 0; level *= 257; return (ioctl(fd, MIXER_WRITE(device), &level)); } void print_help(void) { printf("Syntax: mix [options]\n\ -i Increment by the specified percentage when raising or lowering the volume.\n\ -u Raise the volume.\n\ -d Lower the volume.\n\ -p Use the PCM volume level instead of the master volume level.\n\ -s Set the volume level to the specified percent level.\n\ -h Print this help text and exit.\n\ -v Print version information and exit.\n"); } int main(int argc, char **argv) { int fd; int opt; int device = SOUND_MIXER_VOLUME; int level = -1; int adjustment = 0; int increment = 5; while ((opt = getopt(argc, argv, "hvi:udps:")) != EOF) { switch (opt) { case 'i': { char *end; if (optarg == NULL) { fprintf(stderr, "No increment given"); exit(-1); } increment = strtol(optarg, &end, 10); if (increment == -1) { fprintf(stderr, "Invalid increment given: %s\n", optarg); exit(-1); } break; } case 'u': adjustment = 1; break; case 'd': adjustment = -1; break; case 'p': device = SOUND_MIXER_PCM; break; case 's': { char *end; if (optarg == NULL) { fprintf(stderr, "No volume level specified\n"); exit(-1); } level = strtol(optarg, &end, 10); if (*end != '\0') { fprintf(stderr, "Invalid volume level: %s\n", optarg); exit(-1); } break; } case 'h': print_help(); exit(0); case 'v': printf("mix v1.0 by Ryan McCabe \n"); exit(0); } } fd = open_mixer(); if (fd == -1) exit(-1); if (adjustment != 0) { level = get_level(fd, device); if (level == -1) exit(-1); level += adjustment * increment; } if (level != -1) exit(set_level(fd, device, level)); exit(0); }