📄 amixer.c
字号:
sptr = ptr; if (!strncmp(ptr, "mute", 4) && snd_mixer_selem_has_playback_switch(elem)) { snd_mixer_selem_get_playback_switch(elem, chn, &ival); if (snd_mixer_selem_set_playback_switch(elem, chn, get_bool_simple(&ptr, "mute", 1, ival)) >= 0) check_flag = 1; } else if (!strncmp(ptr, "off", 3) && snd_mixer_selem_has_playback_switch(elem)) { snd_mixer_selem_get_playback_switch(elem, chn, &ival); if (snd_mixer_selem_set_playback_switch(elem, chn, get_bool_simple(&ptr, "off", 1, ival)) >= 0) check_flag = 1; } else if (!strncmp(ptr, "unmute", 6) && snd_mixer_selem_has_playback_switch(elem)) { snd_mixer_selem_get_playback_switch(elem, chn, &ival); if (snd_mixer_selem_set_playback_switch(elem, chn, get_bool_simple(&ptr, "unmute", 0, ival)) >= 0) check_flag = 1; } else if (!strncmp(ptr, "on", 2) && snd_mixer_selem_has_playback_switch(elem)) { snd_mixer_selem_get_playback_switch(elem, chn, &ival); if (snd_mixer_selem_set_playback_switch(elem, chn, get_bool_simple(&ptr, "on", 0, ival)) >= 0) check_flag = 1; } else if (!strncmp(ptr, "toggle", 6) && snd_mixer_selem_has_playback_switch(elem)) { if (firstchn || !snd_mixer_selem_has_playback_switch_joined(elem)) { snd_mixer_selem_get_playback_switch(elem, chn, &ival); if (snd_mixer_selem_set_playback_switch(elem, chn, (ival ? 1 : 0) ^ 1) >= 0) check_flag = 1; } simple_skip_word(&ptr, "toggle"); } else if (isdigit(*ptr) || *ptr == '-' || *ptr == '+') { if (set_volume_simple(elem, chn, &ptr, 0) >= 0) check_flag = 1; } else if (simple_skip_word(&ptr, "cap") || simple_skip_word(&ptr, "rec") || simple_skip_word(&ptr, "nocap") || simple_skip_word(&ptr, "norec")) { /* nothing */ } else { okflag &= ~1; } } if ((dir & 2) && snd_mixer_selem_has_capture_channel(elem, chn)) { if (sptr != NULL) ptr = sptr; sptr = ptr; if (!strncmp(ptr, "cap", 3) && snd_mixer_selem_has_capture_switch(elem)) { snd_mixer_selem_get_capture_switch(elem, chn, &ival); if (snd_mixer_selem_set_capture_switch(elem, chn, get_bool_simple(&ptr, "cap", 0, ival)) >= 0) check_flag = 1; } else if (!strncmp(ptr, "rec", 3) && snd_mixer_selem_has_capture_switch(elem)) { snd_mixer_selem_get_capture_switch(elem, chn, &ival); if (snd_mixer_selem_set_capture_switch(elem, chn, get_bool_simple(&ptr, "rec", 0, ival)) >= 0) check_flag = 1; } else if (!strncmp(ptr, "nocap", 5) && snd_mixer_selem_has_capture_switch(elem)) { snd_mixer_selem_get_capture_switch(elem, chn, &ival); if (snd_mixer_selem_set_capture_switch(elem, chn, get_bool_simple(&ptr, "nocap", 1, ival)) >= 0) check_flag = 1; } else if (!strncmp(ptr, "norec", 5) && snd_mixer_selem_has_capture_switch(elem)) { snd_mixer_selem_get_capture_switch(elem, chn, &ival); if (snd_mixer_selem_set_capture_switch(elem, chn, get_bool_simple(&ptr, "norec", 1, ival)) >= 0) check_flag = 1; } else if (!strncmp(ptr, "toggle", 6) && snd_mixer_selem_has_capture_switch(elem)) { if (firstchn || !snd_mixer_selem_has_capture_switch_joined(elem)) { snd_mixer_selem_get_capture_switch(elem, chn, &ival); if (snd_mixer_selem_set_capture_switch(elem, chn, (ival ? 1 : 0) ^ 1) >= 0) check_flag = 1; } simple_skip_word(&ptr, "toggle"); } else if (isdigit(*ptr) || *ptr == '-' || *ptr == '+') { if (set_volume_simple(elem, chn, &ptr, 1) >= 0) check_flag = 1; } else if (simple_skip_word(&ptr, "mute") || simple_skip_word(&ptr, "off") || simple_skip_word(&ptr, "unmute") || simple_skip_word(&ptr, "on")) { /* nothing */ } else { okflag &= ~2; } } if (okflag == 0) { if (debugflag) { if (dir & 1) error("Unknown playback setup '%s'..", ptr); if (dir & 2) error("Unknown capture setup '%s'..", ptr); } if (! keep_handle) { snd_mixer_close(handle); handle = NULL; } return 0; } if (!multi) ptr = optr; firstchn = 0; } } if (!check_flag) { error("Invalid command!"); if (! keep_handle) { snd_mixer_close(handle); handle = NULL; } return 1; } __skip_write: if (!quiet) { printf("Simple mixer control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); show_selem(handle, sid, " ", 1); } if (! keep_handle) { snd_mixer_close(handle); handle = NULL; } return 0;}static void events_info(snd_hctl_elem_t *helem){ snd_ctl_elem_id_t *id; snd_ctl_elem_id_alloca(&id); snd_hctl_elem_get_id(helem, id); printf("event info: "); show_control_id(id); printf("\n");}static void events_value(snd_hctl_elem_t *helem){ snd_ctl_elem_id_t *id; snd_ctl_elem_id_alloca(&id); snd_hctl_elem_get_id(helem, id); printf("event value: "); show_control_id(id); printf("\n");}static void events_remove(snd_hctl_elem_t *helem){ snd_ctl_elem_id_t *id; snd_ctl_elem_id_alloca(&id); snd_hctl_elem_get_id(helem, id); printf("event remove: "); show_control_id(id); printf("\n");}int element_callback(snd_hctl_elem_t *elem, unsigned int mask){ if (mask == SND_CTL_EVENT_MASK_REMOVE) { events_remove(elem); return 0; } if (mask & SND_CTL_EVENT_MASK_INFO) events_info(elem); if (mask & SND_CTL_EVENT_MASK_VALUE) events_value(elem); return 0;}static void events_add(snd_hctl_elem_t *helem){ snd_ctl_elem_id_t *id; snd_ctl_elem_id_alloca(&id); snd_hctl_elem_get_id(helem, id); printf("event add: "); show_control_id(id); printf("\n"); snd_hctl_elem_set_callback(helem, element_callback);}int ctl_callback(snd_hctl_t *ctl, unsigned int mask, snd_hctl_elem_t *elem){ if (mask & SND_CTL_EVENT_MASK_ADD) events_add(elem); return 0;}static int events(int argc ATTRIBUTE_UNUSED, char *argv[] ATTRIBUTE_UNUSED){ snd_hctl_t *handle; snd_hctl_elem_t *helem; int err; if ((err = snd_hctl_open(&handle, card, 0)) < 0) { error("Control %s open error: %s\n", card, snd_strerror(err)); return err; } snd_hctl_set_callback(handle, ctl_callback); if ((err = snd_hctl_load(handle)) < 0) { error("Control %s hbuild error: %s\n", card, snd_strerror(err)); return err; } for (helem = snd_hctl_first_elem(handle); helem; helem = snd_hctl_elem_next(helem)) { snd_hctl_elem_set_callback(helem, element_callback); } printf("Ready to listen...\n"); while (1) { int res = snd_hctl_wait(handle, -1); if (res >= 0) { printf("Poll ok: %i\n", res); res = snd_hctl_handle_events(handle); assert(res > 0); } } snd_hctl_close(handle); return 0;}static void sevents_value(snd_mixer_selem_id_t *sid){ printf("event value: '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid));}static void sevents_info(snd_mixer_selem_id_t *sid){ printf("event info: '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid));}static void sevents_remove(snd_mixer_selem_id_t *sid){ printf("event remove: '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid));}int melem_event(snd_mixer_elem_t *elem, unsigned int mask){ snd_mixer_selem_id_t *sid; snd_mixer_selem_id_alloca(&sid); snd_mixer_selem_get_id(elem, sid); if (mask == SND_CTL_EVENT_MASK_REMOVE) { sevents_remove(sid); return 0; } if (mask & SND_CTL_EVENT_MASK_INFO) sevents_info(sid); if (mask & SND_CTL_EVENT_MASK_VALUE) sevents_value(sid); return 0;}static void sevents_add(snd_mixer_elem_t *elem){ snd_mixer_selem_id_t *sid; snd_mixer_selem_id_alloca(&sid); snd_mixer_selem_get_id(elem, sid); printf("event add: '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); snd_mixer_elem_set_callback(elem, melem_event);}int mixer_event(snd_mixer_t *mixer, unsigned int mask, snd_mixer_elem_t *elem){ if (mask & SND_CTL_EVENT_MASK_ADD) sevents_add(elem); return 0;}static int sevents(int argc ATTRIBUTE_UNUSED, char *argv[] ATTRIBUTE_UNUSED){ snd_mixer_t *handle; int err; if ((err = snd_mixer_open(&handle, 0)) < 0) { error("Mixer %s open error: %s", card, snd_strerror(err)); return err; } if (smixer_level == 0 && (err = snd_mixer_attach(handle, card)) < 0) { error("Mixer attach %s error: %s", card, snd_strerror(err)); snd_mixer_close(handle); return err; } if ((err = snd_mixer_selem_register(handle, smixer_level > 0 ? &smixer_options : NULL, NULL)) < 0) { error("Mixer register error: %s", snd_strerror(err)); snd_mixer_close(handle); return err; } snd_mixer_set_callback(handle, mixer_event); err = snd_mixer_load(handle); if (err < 0) { error("Mixer %s load error: %s", card, snd_strerror(err)); snd_mixer_close(handle); return err; } printf("Ready to listen...\n"); while (1) { int res; res = snd_mixer_wait(handle, -1); if (res >= 0) { printf("Poll ok: %i\n", res); res = snd_mixer_handle_events(handle); assert(res >= 0); } } snd_mixer_close(handle); return 0;}/* * split a line into tokens * the content in the line buffer is modified */static int split_line(char *buf, char **token, int max_token){ char *dst; int n, esc, quote; for (n = 0; n < max_token; n++) { while (isspace(*buf)) buf++; if (! *buf || *buf == '\n') return n; /* skip comments */ if (*buf == '#' || *buf == '!') return n; esc = 0; quote = 0; token[n] = buf; for (dst = buf; *buf && *buf != '\n'; buf++) { if (esc) esc = 0; else if (isspace(*buf) && !quote) { buf++; break; } else if (*buf == '\\') { esc = 1; continue; } else if (*buf == '\'' || *buf == '"') { if (! quote) { quote = *buf; continue; } else if (*buf == quote) { quote = 0; continue; } } *dst++ = *buf; } *dst = 0; } return n;}#define MAX_ARGS 32static int exec_stdin(void){ int narg; char buf[256], *args[MAX_ARGS]; int err = 0; /* quiet = 1; */ ignore_error = 1; while (fgets(buf, sizeof(buf), stdin)) { narg = split_line(buf, args, MAX_ARGS); if (narg > 0) { if (!strcmp(args[0], "sset") || !strcmp(args[0], "set")) err = sset(narg - 1, args + 1, 0, 1); else if (!strcmp(args[0], "cset")) err = cset(narg - 1, args + 1, 0, 1); if (err < 0) return 1; } } return 0;}int main(int argc, char *argv[]){ int morehelp, level = 0; int read_stdin = 0; static struct option long_option[] = { {"help", 0, NULL, 'h'}, {"card", 1, NULL, 'c'}, {"device", 1, NULL, 'D'}, {"quiet", 0, NULL, 'q'}, {"inactive", 0, NULL, 'i'}, {"debug", 0, NULL, 'd'}, {"nocheck", 0, NULL, 'n'}, {"version", 0, NULL, 'v'}, {"abstract", 1, NULL, 'a'}, {"stdin", 0, NULL, 's'}, {NULL, 0, NULL, 0}, }; morehelp = 0; while (1) { int c; if ((c = getopt_long(argc, argv, "hc:D:qidnva:s", long_option, NULL)) < 0) break; switch (c) { case 'h': help(); return 0; case 'c': { int i; i = snd_card_get_index(optarg); if (i >= 0 && i < 32) sprintf(card, "hw:%i", i); else { fprintf(stderr, "Invalid card number.\n"); morehelp++; } } break; case 'D': strncpy(card, optarg, sizeof(card)-1); card[sizeof(card)-1] = '\0'; break; case 'q': quiet = 1; break; case 'i': level |= LEVEL_INACTIVE; break; case 'd': debugflag = 1; break; case 'n': no_check = 1; break; case 'v': printf("amixer version " SND_UTIL_VERSION_STR "\n"); return 1; case 'a': smixer_level = 1; memset(&smixer_options, 0, sizeof(smixer_options)); smixer_options.ver = 1; if (!strcmp(optarg, "none")) smixer_options.abstract = SND_MIXER_SABSTRACT_NONE; else if (!strcmp(optarg, "basic")) smixer_options.abstract = SND_MIXER_SABSTRACT_BASIC; else { fprintf(stderr, "Select correct abstraction level (none or basic)...\n"); morehelp++; } break; case 's': read_stdin = 1; break; default: fprintf(stderr, "Invalid switch or option needs an argument.\n"); morehelp++; } } if (morehelp) { help(); return 1; } smixer_options.device = card; if (read_stdin) return exec_stdin(); if (argc - optind <= 0) { return selems(LEVEL_BASIC | level) ? 1 : 0; } if (!strcmp(argv[optind], "help")) { return help() ? 1 : 0; } else if (!strcmp(argv[optind], "info")) { return info() ? 1 : 0; } else if (!strcmp(argv[optind], "controls")) { return controls(level) ? 1 : 0; } else if (!strcmp(argv[optind], "contents")) { return controls(LEVEL_BASIC | level) ? 1 : 0; } else if (!strcmp(argv[optind], "scontrols") || !strcmp(argv[optind], "simple")) { return selems(level) ? 1 : 0; } else if (!strcmp(argv[optind], "scontents")) { return selems(LEVEL_BASIC | level) ? 1 : 0; } else if (!strcmp(argv[optind], "sset") || !strcmp(argv[optind], "set")) { return sset(argc - optind - 1, argc - optind > 1 ? argv + optind + 1 : NULL, 0, 0) ? 1 : 0; } else if (!strcmp(argv[optind], "sget") || !strcmp(argv[optind], "get")) { return sset(argc - optind - 1, argc - optind > 1 ? argv + optind + 1 : NULL, 1, 0) ? 1 : 0; } else if (!strcmp(argv[optind], "cset")) { return cset(argc - optind - 1, argc - optind > 1 ? argv + optind + 1 : NULL, 0, 0) ? 1 : 0; } else if (!strcmp(argv[optind], "cget")) { return cset(argc - optind - 1, argc - optind > 1 ? argv + optind + 1 : NULL, 1, 0) ? 1 : 0; } else if (!strcmp(argv[optind], "events")) { return events(argc - optind - 1, argc - optind > 1 ? argv + optind + 1 : NULL); } else if (!strcmp(argv[optind], "sevents")) { return sevents(argc - optind - 1, argc - optind > 1 ? argv + optind + 1 : NULL); } else { fprintf(stderr, "amixer: Unknown command '%s'...\n", argv[optind]); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -