/* vim: tabstop=4 shiftwidth=4 noexpandtab * This file is part of ToaruOS and is released under the terms * of the NCSA / University of Illinois License - see LICENSE.md * Copyright (C) 2015 Mike Gerow */ #include #include #include #include #include #include static char usage[] = "%s - Control audio mixer settings.\n" "\n" "Usage %s [-d device_id] -l\n" " %s [-d device_id] [-k knob_id] -r\n" " %s [-d device_id] [-k knob_id] -w knob_value\n" " %s -h\n" "\n" " -d: \033[3mDevice id to address. Defaults to the main sound device.\033[0m\n" " -l: \033[3mList the knobs on a device.\033[0m\n" " -k: \033[3mKnob id to address. Defaults to the device's master knob.\033[0m\n" " -r: \033[3mPerform a read on the given device's knob. Defaults to the device's\n" " master knob.\033[0m\n" " -w: \033[3mPerform a write on the given device's knob. The value should be a\n" " float from 0.0 to 1.0.\033[0m\n" " -h: \033[3mPrint this help message and exit.\033[0m\n"; int main(int argc, char * argv[]) { uint32_t device_id = SND_DEVICE_MAIN; uint32_t knob_id = SND_KNOB_MASTER; uint8_t list_flag = 0; uint8_t read_flag = 0; uint8_t write_flag = 0; double write_value = 0.0; int c; while ((c = getopt(argc, argv, "d:lk:rw:h?")) != -1) { switch (c) { case 'd': device_id = atoi(optarg); break; case 'l': list_flag = 1; break; case 'k': knob_id = atoi(optarg); break; case 'r': read_flag = 1; break; case 'w': write_flag = 1; write_value = atof(optarg); if (write_value < 0.0 || write_value > 1.0) { fprintf(stderr, "argument -w value must be between 0.0 and 1.0\n"); exit(EXIT_FAILURE); } break; case 'h': case '?': default: fprintf(stderr, usage, argv[0], argv[0], argv[0], argv[0], argv[0]); exit(EXIT_FAILURE); } } int mixer = open("/dev/mixer", O_RDONLY); if (mixer < 1) { //perror("open"); exit(EXIT_FAILURE); } if (list_flag) { snd_knob_list_t list = {0}; list.device = device_id; if (ioctl(mixer, SND_MIXER_GET_KNOBS, &list) < 0) { perror("ioctl"); exit(EXIT_FAILURE); } for (uint32_t i = 0; i < list.num; i++) { snd_knob_info_t info = {0}; info.device = device_id; info.id = list.ids[i]; if (ioctl(mixer, SND_MIXER_GET_KNOB_INFO, &info) < 0) { perror("ioctl"); exit(EXIT_FAILURE); } fprintf(stdout, "%d: %s\n", (unsigned int)info.id, info.name); } exit(EXIT_SUCCESS); } if (read_flag) { snd_knob_value_t value = {0}; value.device = device_id; value.id = knob_id; if (ioctl(mixer, SND_MIXER_READ_KNOB, &value) < 0) { perror("ioctl"); exit(EXIT_FAILURE); } double double_val = (double)value.val / SND_KNOB_MAX_VALUE; fprintf(stdout, "%f\n", double_val); exit(EXIT_FAILURE); } if (write_flag) { snd_knob_value_t value = {0}; value.device = device_id; value.id = knob_id; value.val = (uint32_t)(write_value * SND_KNOB_MAX_VALUE); if (ioctl(mixer, SND_MIXER_WRITE_KNOB, &value) < 0) { perror("ioctl"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } fprintf(stderr, "No operation specified.\n"); exit(EXIT_FAILURE); }