📄 amixer.c
字号:
while (size > 0) { printf("0x%x", tlv[idx++]); size -= sizeof(unsigned int); } } else { printf("min="); print_dB(tlv[2]); printf(",step="); print_dB(tlv[3] & 0xffff); printf(",mute=%i", (tlv[3] >> 16) & 1); } break;#ifdef SND_CTL_TLVT_DB_LINEAR case SND_CTL_TLVT_DB_LINEAR: printf("dBlinear-"); if (size != 2 * sizeof(unsigned int)) { while (size > 0) { printf("0x%x", tlv[idx++]); size -= sizeof(unsigned int); } } else { printf("min="); print_dB(tlv[2]); printf(",max="); print_dB(tlv[3]); } break;#endif default: printf("unk-%i-", type); while (size > 0) { printf("0x%x", tlv[idx++]); size -= sizeof(unsigned int); } break; } putc('\n', stdout);}static int show_control(const char *space, snd_hctl_elem_t *elem, int level){ int err; unsigned int item, idx, count, *tlv; snd_ctl_elem_type_t type; snd_ctl_elem_id_t *id; snd_ctl_elem_info_t *info; snd_ctl_elem_value_t *control; snd_aes_iec958_t iec958; snd_ctl_elem_id_alloca(&id); snd_ctl_elem_info_alloca(&info); snd_ctl_elem_value_alloca(&control); if ((err = snd_hctl_elem_info(elem, info)) < 0) { error("Control %s snd_hctl_elem_info error: %s\n", card, snd_strerror(err)); return err; } if (level & LEVEL_ID) { snd_hctl_elem_get_id(elem, id); show_control_id(id); printf("\n"); } count = snd_ctl_elem_info_get_count(info); type = snd_ctl_elem_info_get_type(info); printf("%s; type=%s,access=%s,values=%i", space, control_type(info), control_access(info), count); switch (type) { case SND_CTL_ELEM_TYPE_INTEGER: printf(",min=%li,max=%li,step=%li\n", snd_ctl_elem_info_get_min(info), snd_ctl_elem_info_get_max(info), snd_ctl_elem_info_get_step(info)); break; case SND_CTL_ELEM_TYPE_INTEGER64: printf(",min=%Li,max=%Li,step=%Li\n", snd_ctl_elem_info_get_min64(info), snd_ctl_elem_info_get_max64(info), snd_ctl_elem_info_get_step64(info)); break; case SND_CTL_ELEM_TYPE_ENUMERATED: { unsigned int items = snd_ctl_elem_info_get_items(info); printf(",items=%u\n", items); for (item = 0; item < items; item++) { snd_ctl_elem_info_set_item(info, item); if ((err = snd_hctl_elem_info(elem, info)) < 0) { error("Control %s element info error: %s\n", card, snd_strerror(err)); return err; } printf("%s; Item #%u '%s'\n", space, item, snd_ctl_elem_info_get_item_name(info)); } break; } default: printf("\n"); break; } if (level & LEVEL_BASIC) { if ((err = snd_hctl_elem_read(elem, control)) < 0) { error("Control %s element read error: %s\n", card, snd_strerror(err)); return err; } printf("%s: values=", space); for (idx = 0; idx < count; idx++) { if (idx > 0) printf(","); switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: printf("%s", snd_ctl_elem_value_get_boolean(control, idx) ? "on" : "off"); break; case SND_CTL_ELEM_TYPE_INTEGER: printf("%li", snd_ctl_elem_value_get_integer(control, idx)); break; case SND_CTL_ELEM_TYPE_INTEGER64: printf("%Li", snd_ctl_elem_value_get_integer64(control, idx)); break; case SND_CTL_ELEM_TYPE_ENUMERATED: printf("%u", snd_ctl_elem_value_get_enumerated(control, idx)); break; case SND_CTL_ELEM_TYPE_BYTES: printf("0x%02x", snd_ctl_elem_value_get_byte(control, idx)); break; case SND_CTL_ELEM_TYPE_IEC958: snd_ctl_elem_value_get_iec958(control, &iec958); printf("[AES0=0x%02x AES1=0x%02x AES2=0x%02x AES3=0x%02x]", iec958.status[0], iec958.status[1], iec958.status[2], iec958.status[3]); break; default: printf("?"); break; } } printf("\n"); if (!snd_ctl_elem_info_is_tlv_readable(info)) goto __skip_tlv; tlv = malloc(4096); if ((err = snd_hctl_elem_tlv_read(elem, tlv, 4096)) < 0) { error("Control %s element TLV read error: %s\n", card, snd_strerror(err)); free(tlv); return err; } decode_tlv(strlen(space), tlv, 4096); free(tlv); } __skip_tlv: return 0;}static int controls(int level){ int err; snd_hctl_t *handle; snd_hctl_elem_t *elem; snd_ctl_elem_id_t *id; snd_ctl_elem_info_t *info; snd_ctl_elem_id_alloca(&id); snd_ctl_elem_info_alloca(&info); if ((err = snd_hctl_open(&handle, card, 0)) < 0) { error("Control %s open error: %s", card, snd_strerror(err)); return err; } if ((err = snd_hctl_load(handle)) < 0) { error("Control %s local error: %s\n", card, snd_strerror(err)); return err; } for (elem = snd_hctl_first_elem(handle); elem; elem = snd_hctl_elem_next(elem)) { if ((err = snd_hctl_elem_info(elem, info)) < 0) { error("Control %s snd_hctl_elem_info error: %s\n", card, snd_strerror(err)); return err; } if (!(level & LEVEL_INACTIVE) && snd_ctl_elem_info_is_inactive(info)) continue; snd_hctl_elem_get_id(elem, id); show_control_id(id); printf("\n"); if (level & LEVEL_BASIC) show_control(" ", elem, 1); } snd_hctl_close(handle); return 0;}static int show_selem(snd_mixer_t *handle, snd_mixer_selem_id_t *id, const char *space, int level){ snd_mixer_selem_channel_id_t chn; long pmin = 0, pmax = 0; long cmin = 0, cmax = 0; long pvol, cvol; int psw, csw; int pmono, cmono, mono_ok = 0; long db; snd_mixer_elem_t *elem; elem = snd_mixer_find_selem(handle, id); if (!elem) { error("Mixer %s simple element not found", card); return -ENOENT; } if (level & LEVEL_BASIC) { printf("%sCapabilities:", space); if (snd_mixer_selem_has_common_volume(elem)) { printf(" volume"); if (snd_mixer_selem_has_playback_volume_joined(elem)) printf(" volume-joined"); } else { if (snd_mixer_selem_has_playback_volume(elem)) { printf(" pvolume"); if (snd_mixer_selem_has_playback_volume_joined(elem)) printf(" pvolume-joined"); } if (snd_mixer_selem_has_capture_volume(elem)) { printf(" cvolume"); if (snd_mixer_selem_has_capture_volume_joined(elem)) printf(" cvolume-joined"); } } if (snd_mixer_selem_has_common_switch(elem)) { printf(" switch"); if (snd_mixer_selem_has_playback_switch_joined(elem)) printf(" switch-joined"); } else { if (snd_mixer_selem_has_playback_switch(elem)) { printf(" pswitch"); if (snd_mixer_selem_has_playback_switch_joined(elem)) printf(" pswitch-joined"); } if (snd_mixer_selem_has_capture_switch(elem)) { printf(" cswitch"); if (snd_mixer_selem_has_capture_switch_joined(elem)) printf(" cswitch-joined"); if (snd_mixer_selem_has_capture_switch_exclusive(elem)) printf(" cswitch-exclusive"); } } if (snd_mixer_selem_is_enum_playback(elem)) { printf(" penum"); } else if (snd_mixer_selem_is_enum_capture(elem)) { printf(" cenum"); } else if (snd_mixer_selem_is_enumerated(elem)) { printf(" enum"); } printf("\n"); if (snd_mixer_selem_is_enumerated(elem)) { int i, items; unsigned int idx; char itemname[40]; items = snd_mixer_selem_get_enum_items(elem); printf(" Items:"); for (i = 0; i < items; i++) { snd_mixer_selem_get_enum_item_name(elem, i, sizeof(itemname) - 1, itemname); printf(" '%s'", itemname); } printf("\n"); for (i = 0; !snd_mixer_selem_get_enum_item(elem, i, &idx); i++) { snd_mixer_selem_get_enum_item_name(elem, idx, sizeof(itemname) - 1, itemname); printf(" Item%d: '%s'\n", i, itemname); } return 0; /* no more thing to do */ } if (snd_mixer_selem_has_capture_switch_exclusive(elem)) printf("%sCapture exclusive group: %i\n", space, snd_mixer_selem_get_capture_group(elem)); if (snd_mixer_selem_has_playback_volume(elem) || snd_mixer_selem_has_playback_switch(elem)) { printf("%sPlayback channels:", space); if (snd_mixer_selem_is_playback_mono(elem)) { printf(" Mono"); } else { int first = 1; for (chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++){ if (!snd_mixer_selem_has_playback_channel(elem, chn)) continue; if (!first) printf(" -"); printf(" %s", snd_mixer_selem_channel_name(chn)); first = 0; } } printf("\n"); } if (snd_mixer_selem_has_capture_volume(elem) || snd_mixer_selem_has_capture_switch(elem)) { printf("%sCapture channels:", space); if (snd_mixer_selem_is_capture_mono(elem)) { printf(" Mono"); } else { int first = 1; for (chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++){ if (!snd_mixer_selem_has_capture_channel(elem, chn)) continue; if (!first) printf(" -"); printf(" %s", snd_mixer_selem_channel_name(chn)); first = 0; } } printf("\n"); } if (snd_mixer_selem_has_playback_volume(elem) || snd_mixer_selem_has_capture_volume(elem)) { printf("%sLimits:", space); if (snd_mixer_selem_has_common_volume(elem)) { snd_mixer_selem_get_playback_volume_range(elem, &pmin, &pmax); snd_mixer_selem_get_capture_volume_range(elem, &cmin, &cmax); printf(" %li - %li", pmin, pmax); } else { if (snd_mixer_selem_has_playback_volume(elem)) { snd_mixer_selem_get_playback_volume_range(elem, &pmin, &pmax); printf(" Playback %li - %li", pmin, pmax); } if (snd_mixer_selem_has_capture_volume(elem)) { snd_mixer_selem_get_capture_volume_range(elem, &cmin, &cmax); printf(" Capture %li - %li", cmin, cmax); } } printf("\n"); } pmono = snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_MONO) && (snd_mixer_selem_is_playback_mono(elem) || (!snd_mixer_selem_has_playback_volume(elem) && !snd_mixer_selem_has_playback_switch(elem))); cmono = snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_MONO) && (snd_mixer_selem_is_capture_mono(elem) || (!snd_mixer_selem_has_capture_volume(elem) && !snd_mixer_selem_has_capture_switch(elem)));#if 0 printf("pmono = %i, cmono = %i (%i, %i, %i, %i)\n", pmono, cmono, snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_MONO), snd_mixer_selem_is_capture_mono(elem), snd_mixer_selem_has_capture_volume(elem), snd_mixer_selem_has_capture_switch(elem));#endif if (pmono || cmono) { if (!mono_ok) { printf("%s%s:", space, "Mono"); mono_ok = 1; } if (snd_mixer_selem_has_common_volume(elem)) { snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &pvol); printf(" %s", get_percent(pvol, pmin, pmax)); if (!snd_mixer_selem_get_playback_dB(elem, SND_MIXER_SCHN_MONO, &db)) { printf(" ["); print_dB(db); printf("]"); } } if (snd_mixer_selem_has_common_switch(elem)) { snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_MONO, &psw); printf(" [%s]", psw ? "on" : "off"); } } if (pmono && snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_MONO)) { int title = 0; if (!mono_ok) { printf("%s%s:", space, "Mono"); mono_ok = 1; } if (!snd_mixer_selem_has_common_volume(elem)) { if (snd_mixer_selem_has_playback_volume(elem)) { printf(" Playback"); title = 1; snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &pvol); printf(" %s", get_percent(pvol, pmin, pmax)); if (!snd_mixer_selem_get_playback_dB(elem, SND_MIXER_SCHN_MONO, &db)) { printf(" ["); print_dB(db); printf("]"); } } } if (!snd_mixer_selem_has_common_switch(elem)) { if (snd_mixer_selem_has_playback_switch(elem)) { if (!title) printf(" Playback"); snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_MONO, &psw); printf(" [%s]", psw ? "on" : "off"); } } } if (cmono && snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_MONO)) { int title = 0; if (!mono_ok) { printf("%s%s:", space, "Mono"); mono_ok = 1; } if (!snd_mixer_selem_has_common_volume(elem)) { if (snd_mixer_selem_has_capture_volume(elem)) { printf(" Capture"); title = 1; snd_mixer_selem_get_capture_volume(elem, SND_MIXER_SCHN_MONO, &cvol); printf(" %s", get_percent(cvol, cmin, cmax)); if (!snd_mixer_selem_get_capture_dB(elem, SND_MIXER_SCHN_MONO, &db)) { printf(" ["); print_dB(db); printf("]"); } } } if (!snd_mixer_selem_has_common_switch(elem)) { if (snd_mixer_selem_has_capture_switch(elem)) { if (!title) printf(" Capture"); snd_mixer_selem_get_capture_switch(elem, SND_MIXER_SCHN_MONO, &csw); printf(" [%s]", csw ? "on" : "off"); } } } if (pmono || cmono) printf("\n"); if (!pmono || !cmono) { for (chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++) { if ((pmono || !snd_mixer_selem_has_playback_channel(elem, chn)) && (cmono || !snd_mixer_selem_has_capture_channel(elem, chn))) continue; printf("%s%s:", space, snd_mixer_selem_channel_name(chn)); if (!pmono && !cmono && snd_mixer_selem_has_common_volume(elem)) { snd_mixer_selem_get_playback_volume(elem, chn, &pvol); printf(" %s", get_percent(pvol, pmin, pmax)); if (!snd_mixer_selem_get_playback_dB(elem, chn, &db)) { printf(" ["); print_dB(db); printf("]"); } } if (!pmono && !cmono && snd_mixer_selem_has_common_switch(elem)) { snd_mixer_selem_get_playback_switch(elem, chn, &psw); printf(" [%s]", psw ? "on" : "off"); } if (!pmono && snd_mixer_selem_has_playback_channel(elem, chn)) { int title = 0; if (!snd_mixer_selem_has_common_volume(elem)) { if (snd_mixer_selem_has_playback_volume(elem)) { printf(" Playback"); title = 1; snd_mixer_selem_get_playback_volume(elem, chn, &pvol); printf(" %s", get_percent(pvol, pmin, pmax)); if (!snd_mixer_selem_get_playback_dB(elem, chn, &db)) { printf(" ["); print_dB(db); printf("]"); } } } if (!snd_mixer_selem_has_common_switch(elem)) { if (snd_mixer_selem_has_playback_switch(elem)) { if (!title) printf(" Playback"); snd_mixer_selem_get_playback_switch(elem, chn, &psw); printf(" [%s]", psw ? "on" : "off"); } } } if (!cmono && snd_mixer_selem_has_capture_channel(elem, chn)) { int title = 0; if (!snd_mixer_selem_has_common_volume(elem)) { if (snd_mixer_selem_has_capture_volume(elem)) { printf(" Capture"); title = 1; snd_mixer_selem_get_capture_volume(elem, chn, &cvol); printf(" %s", get_percent(cvol, cmin, cmax)); if (!snd_mixer_selem_get_capture_dB(elem, chn, &db)) { printf(" ["); print_dB(db); printf("]"); } } } if (!snd_mixer_selem_has_common_switch(elem)) { if (snd_mixer_selem_has_capture_switch(elem)) { if (!title) printf(" Capture"); snd_mixer_selem_get_capture_switch(elem, chn, &csw); printf(" [%s]", csw ? "on" : "off"); } } } printf("\n"); } } } return 0;}static int selems(int level){ int err; snd_mixer_t *handle;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -