mixerctl.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /* vim: tabstop=4 shiftwidth=4 noexpandtab
  2. * This file is part of ToaruOS and is released under the terms
  3. * of the NCSA / University of Illinois License - see LICENSE.md
  4. * Copyright (C) 2015 Mike Gerow
  5. */
  6. #include <fcntl.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <sys/ioctl.h>
  10. #include <unistd.h>
  11. #include <kernel/mod/sound.h>
  12. static char usage[] =
  13. "%s - Control audio mixer settings.\n"
  14. "\n"
  15. "Usage %s [-d device_id] -l\n"
  16. " %s [-d device_id] [-k knob_id] -r\n"
  17. " %s [-d device_id] [-k knob_id] -w knob_value\n"
  18. " %s -h\n"
  19. "\n"
  20. " -d: \033[3mDevice id to address. Defaults to the main sound device.\033[0m\n"
  21. " -l: \033[3mList the knobs on a device.\033[0m\n"
  22. " -k: \033[3mKnob id to address. Defaults to the device's master knob.\033[0m\n"
  23. " -r: \033[3mPerform a read on the given device's knob. Defaults to the device's\n"
  24. " master knob.\033[0m\n"
  25. " -w: \033[3mPerform a write on the given device's knob. The value should be a\n"
  26. " float from 0.0 to 1.0.\033[0m\n"
  27. " -h: \033[3mPrint this help message and exit.\033[0m\n";
  28. int main(int argc, char * argv[]) {
  29. uint32_t device_id = SND_DEVICE_MAIN;
  30. uint32_t knob_id = SND_KNOB_MASTER;
  31. uint8_t list_flag = 0;
  32. uint8_t read_flag = 0;
  33. uint8_t write_flag = 0;
  34. double write_value = 0.0;
  35. int c;
  36. while ((c = getopt(argc, argv, "d:lk:rw:h?")) != -1) {
  37. switch (c) {
  38. case 'd':
  39. device_id = atoi(optarg);
  40. break;
  41. case 'l':
  42. list_flag = 1;
  43. break;
  44. case 'k':
  45. knob_id = atoi(optarg);
  46. break;
  47. case 'r':
  48. read_flag = 1;
  49. break;
  50. case 'w':
  51. write_flag = 1;
  52. write_value = atof(optarg);
  53. if (write_value < 0.0 || write_value > 1.0) {
  54. fprintf(stderr, "argument -w value must be between 0.0 and 1.0\n");
  55. exit(EXIT_FAILURE);
  56. }
  57. break;
  58. case 'h':
  59. case '?':
  60. default:
  61. fprintf(stderr, usage, argv[0], argv[0], argv[0], argv[0], argv[0]);
  62. exit(EXIT_FAILURE);
  63. }
  64. }
  65. int mixer = open("/dev/mixer", O_RDONLY);
  66. if (mixer < 1) {
  67. //perror("open");
  68. exit(EXIT_FAILURE);
  69. }
  70. if (list_flag) {
  71. snd_knob_list_t list = {0};
  72. list.device = device_id;
  73. if (ioctl(mixer, SND_MIXER_GET_KNOBS, &list) < 0) {
  74. perror("ioctl");
  75. exit(EXIT_FAILURE);
  76. }
  77. for (uint32_t i = 0; i < list.num; i++) {
  78. snd_knob_info_t info = {0};
  79. info.device = device_id;
  80. info.id = list.ids[i];
  81. if (ioctl(mixer, SND_MIXER_GET_KNOB_INFO, &info) < 0) {
  82. perror("ioctl");
  83. exit(EXIT_FAILURE);
  84. }
  85. fprintf(stdout, "%d: %s\n", (unsigned int)info.id, info.name);
  86. }
  87. exit(EXIT_SUCCESS);
  88. }
  89. if (read_flag) {
  90. snd_knob_value_t value = {0};
  91. value.device = device_id;
  92. value.id = knob_id;
  93. if (ioctl(mixer, SND_MIXER_READ_KNOB, &value) < 0) {
  94. perror("ioctl");
  95. exit(EXIT_FAILURE);
  96. }
  97. double double_val = (double)value.val / SND_KNOB_MAX_VALUE;
  98. fprintf(stdout, "%f\n", double_val);
  99. exit(EXIT_FAILURE);
  100. }
  101. if (write_flag) {
  102. snd_knob_value_t value = {0};
  103. value.device = device_id;
  104. value.id = knob_id;
  105. value.val = (uint32_t)(write_value * SND_KNOB_MAX_VALUE);
  106. if (ioctl(mixer, SND_MIXER_WRITE_KNOB, &value) < 0) {
  107. perror("ioctl");
  108. exit(EXIT_FAILURE);
  109. }
  110. exit(EXIT_SUCCESS);
  111. }
  112. fprintf(stderr, "No operation specified.\n");
  113. exit(EXIT_FAILURE);
  114. }