switchsound.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. switchsound.c - a FreeBSD utility to toggle between speakers and
  3. headphone jack sound output. Requires the built-in mixer(8) utility.
  4. This program is Free Software released under the terms and conditions of
  5. the GNU GPL v3. See https://www.gnu.org/licenses for more information.
  6. */
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. // Some hardcoded constants:
  11. #define TUNABLE "sysctl hw.snd.default_unit"
  12. // The maximum output of this command is about 27char, so have a buffer:
  13. #define CMD_OUTPUT_MAX 32
  14. int
  15. get_default_unit()
  16. {
  17. int status = 0;
  18. FILE* p = popen(TUNABLE, "r");
  19. if (!p) {
  20. printf("Error: failed to query sound status!\n");
  21. return -1;
  22. }
  23. // buffer to read output from command.
  24. char output[CMD_OUTPUT_MAX];
  25. fgets(output, CMD_OUTPUT_MAX, p);
  26. for (int i = 0; i < CMD_OUTPUT_MAX; i++) {
  27. if (output[i] == '\n') {
  28. output[i] = '\0';
  29. }
  30. }
  31. // can "cheat" here because the length is always the same:
  32. status = atoi(&output[21]);
  33. //printf("The command seems to return sound device %d\n", status);
  34. pclose(p);
  35. return status;
  36. }
  37. int
  38. set_default_unit()
  39. {
  40. FILE* proc;
  41. char* command;
  42. char buffer[CMD_OUTPUT_MAX];
  43. int unit = get_default_unit();
  44. if (unit == 0) {
  45. unit = 1;
  46. asprintf(&command, "%s=1", TUNABLE);
  47. }
  48. else {
  49. unit = 0;
  50. asprintf(&command, "%s=0", TUNABLE);
  51. }
  52. printf("Toggling to sound unit %d\n", unit);
  53. proc = popen(command, "r");
  54. if (proc == NULL) {
  55. printf("Command failed.\n");
  56. return -1;
  57. }
  58. // do "something" so the command gets executed.
  59. fgets(buffer, CMD_OUTPUT_MAX, proc);
  60. pclose(proc);
  61. free(command);
  62. return get_default_unit();
  63. }
  64. int
  65. main(int argc, char* argv[])
  66. {
  67. int unit = get_default_unit();
  68. unit = set_default_unit();
  69. printf("The default unit is now: %d\n", unit);
  70. return 0;
  71. }