📄 state.c
字号:
} if (strcmp(fld, "subdevice") == 0) { if (snd_config_get_type(n) != SND_CONFIG_TYPE_INTEGER) { error("control.%d.%s is invalid", numid, fld); return -EINVAL; } snd_config_get_integer(n, &subdevice); continue; } if (strcmp(fld, "name") == 0) { if (snd_config_get_type(n) != SND_CONFIG_TYPE_STRING) { error("control.%d.%s is invalid", numid, fld); return -EINVAL; } snd_config_get_string(n, &name); continue; } if (strcmp(fld, "index") == 0) { if (snd_config_get_type(n) != SND_CONFIG_TYPE_INTEGER) { error("control.%d.%s is invalid", numid, fld); return -EINVAL; } snd_config_get_integer(n, &index); continue; } if (strcmp(fld, "value") == 0) { value = n; continue; } error("unknown control.%d.%s field", numid, fld); } if (!value) { error("missing control.%d.value", numid); return -EINVAL; } if (device < 0) device = 0; if (subdevice < 0) subdevice = 0; if (index < 0) index = 0; err = -EINVAL; if (! force_restore) { snd_ctl_elem_info_set_numid(info, numid); err = snd_ctl_elem_info(handle, info); } if (err < 0) { if (iface >= 0 && name) { snd_ctl_elem_info_set_numid(info, 0); snd_ctl_elem_info_set_interface(info, iface); snd_ctl_elem_info_set_device(info, device); snd_ctl_elem_info_set_subdevice(info, subdevice); snd_ctl_elem_info_set_name(info, name); snd_ctl_elem_info_set_index(info, index); err = snd_ctl_elem_info(handle, info); if (err < 0 && comment && is_user_control(comment)) { err = add_user_control(handle, info, comment); if (err < 0) { error("failed to add user control #%d (%s)", numid, snd_strerror(err)); return err; } } } } if (err < 0) { error("failed to obtain info for control #%d (%s)", numid, snd_strerror(err)); return -ENOENT; } numid1 = snd_ctl_elem_info_get_numid(info); iface1 = snd_ctl_elem_info_get_interface(info); device1 = snd_ctl_elem_info_get_device(info); subdevice1 = snd_ctl_elem_info_get_subdevice(info); name1 = snd_ctl_elem_info_get_name(info); index1 = snd_ctl_elem_info_get_index(info); count = snd_ctl_elem_info_get_count(info); type = snd_ctl_elem_info_get_type(info); if (err |= numid != numid1 && ! force_restore) error("warning: numid mismatch (%d/%d) for control #%d", numid, numid1, numid); if (err |= iface != iface1) error("warning: iface mismatch (%d/%d) for control #%d", iface, iface1, numid); if (err |= device != device1) error("warning: device mismatch (%ld/%ld) for control #%d", device, device1, numid); if (err |= subdevice != subdevice1) error("warning: subdevice mismatch (%ld/%ld) for control #%d", subdevice, subdevice1, numid); if (err |= strcmp(name, name1)) error("warning: name mismatch (%s/%s) for control #%d", name, name1, numid); if (err |= index != index1) error("warning: index mismatch (%ld/%ld) for control #%d", index, index1, numid); if (err < 0) { error("failed to obtain info for control #%d (%s)", numid, snd_strerror(err)); return -ENOENT; }#if 0 if (comment) { check_comment_type(comment, type); if (type == SND_CTL_ELEM_TYPE_INTEGER || type == SND_CTL_ELEM_TYPE_INTEGER64) check_comment_range(comment, info); }#endif if (!snd_ctl_elem_info_is_writable(info)) return 0; snd_ctl_elem_value_set_numid(ctl, numid1); if (count == 1) { switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: val = config_bool(value); if (val >= 0) { snd_ctl_elem_value_set_boolean(ctl, 0, val); goto _ok; } break; case SND_CTL_ELEM_TYPE_INTEGER: err = snd_config_get_integer(value, &val); if (err == 0) { snd_ctl_elem_value_set_integer(ctl, 0, val); goto _ok; } break; case SND_CTL_ELEM_TYPE_INTEGER64: err = snd_config_get_integer64(value, &lval); if (err == 0) { snd_ctl_elem_value_set_integer64(ctl, 0, lval); goto _ok; } break; case SND_CTL_ELEM_TYPE_ENUMERATED: val = config_enumerated(value, handle, info); if (val >= 0) { snd_ctl_elem_value_set_enumerated(ctl, 0, val); goto _ok; } break; case SND_CTL_ELEM_TYPE_BYTES: case SND_CTL_ELEM_TYPE_IEC958: break; default: error("Unknow control type: %d", type); return -EINVAL; } } switch (type) { case SND_CTL_ELEM_TYPE_BYTES: case SND_CTL_ELEM_TYPE_IEC958: { const char *buf; err = snd_config_get_string(value, &buf); if (err >= 0) { int c1 = 0; int len = strlen(buf); unsigned int idx = 0; int size = type == SND_CTL_ELEM_TYPE_BYTES ? count : sizeof(snd_aes_iec958_t); if (size * 2 != len) { error("bad control.%d.value contents\n", numid); return -EINVAL; } while (*buf) { int c = *buf++; if ((c = hextodigit(c)) < 0) { error("bad control.%d.value contents\n", numid); return -EINVAL; } if (idx % 2 == 1) snd_ctl_elem_value_set_byte(ctl, idx / 2, c1 << 4 | c); else c1 = c; idx++; } goto _ok; } } default: break; } if (snd_config_get_type(value) != SND_CONFIG_TYPE_COMPOUND) { error("bad control.%d.value type", numid); return -EINVAL; } set = (char*) alloca(count); memset(set, 0, count); snd_config_for_each(i, next, value) { snd_config_t *n = snd_config_iterator_entry(i); const char *id; if (snd_config_get_id(n, &id) < 0) continue; idx = atoi(id); if (idx < 0 || idx >= count || set[idx]) { error("bad control.%d.value index", numid); return -EINVAL; } switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: val = config_bool(n); if (val < 0) { error("bad control.%d.value.%d content", numid, idx); return -EINVAL; } snd_ctl_elem_value_set_boolean(ctl, idx, val); break; case SND_CTL_ELEM_TYPE_INTEGER: err = snd_config_get_integer(n, &val); if (err < 0) { error("bad control.%d.value.%d content", numid, idx); return -EINVAL; } snd_ctl_elem_value_set_integer(ctl, idx, val); break; case SND_CTL_ELEM_TYPE_INTEGER64: err = snd_config_get_integer64(n, &lval); if (err < 0) { error("bad control.%d.value.%d content", numid, idx); return -EINVAL; } snd_ctl_elem_value_set_integer64(ctl, idx, lval); break; case SND_CTL_ELEM_TYPE_ENUMERATED: val = config_enumerated(n, handle, info); if (val < 0) { error("bad control.%d.value.%d content", numid, idx); return -EINVAL; } snd_ctl_elem_value_set_enumerated(ctl, idx, val); break; case SND_CTL_ELEM_TYPE_BYTES: case SND_CTL_ELEM_TYPE_IEC958: err = snd_config_get_integer(n, &val); if (err < 0 || val < 0 || val > 255) { error("bad control.%d.value.%d content", numid, idx); return -EINVAL; } snd_ctl_elem_value_set_byte(ctl, idx, val); break; default: break; } set[idx] = 1; } for (idx = 0; idx < count; ++idx) { if (!set[idx]) { error("control.%d.value.%d is not specified", numid, idx); return -EINVAL; } } _ok: err = snd_ctl_elem_write(handle, ctl); if (err < 0) { error("Cannot write control '%d:%ld:%ld:%s:%ld' : %s", (int)iface, device, subdevice, name, index, snd_strerror(err)); return err; } return 0;}static int set_controls(int card, snd_config_t *top){ snd_ctl_t *handle; snd_ctl_card_info_t *info; snd_config_t *control; snd_config_iterator_t i, next; int err; char name[32], tmpid[16]; const char *id; snd_ctl_card_info_alloca(&info); sprintf(name, "hw:%d", card); err = snd_ctl_open(&handle, name, 0); if (err < 0) { error("snd_ctl_open error: %s", snd_strerror(err)); return err; } err = snd_ctl_card_info(handle, info); if (err < 0) { error("snd_ctl_card_info error: %s", snd_strerror(err)); goto _close; } id = snd_ctl_card_info_get_id(info); err = snd_config_searchv(top, &control, "state", id, "control", 0); if (err < 0) { if (force_restore) { sprintf(tmpid, "card%d", card); err = snd_config_searchv(top, &control, "state", tmpid, "control", 0); if (! err) id = tmpid; } if (err < 0) { fprintf(stderr, "No state is present for card %s\n", id); goto _close; } id = tmpid; } if (snd_config_get_type(control) != SND_CONFIG_TYPE_COMPOUND) { error("state.%s.control is not a compound\n", id); return -EINVAL; } snd_config_for_each(i, next, control) { snd_config_t *n = snd_config_iterator_entry(i); err = set_control(handle, n); if (err < 0 && ! force_restore) goto _close; } _close: snd_ctl_close(handle); return err;}int save_state(const char *file, const char *cardname){ int err; snd_config_t *config; snd_input_t *in; snd_output_t *out; int stdio; err = snd_config_top(&config); if (err < 0) { error("snd_config_top error: %s", snd_strerror(err)); return err; } stdio = !strcmp(file, "-"); if (!stdio && (err = snd_input_stdio_open(&in, file, "r")) >= 0) { err = snd_config_load(config, in); snd_input_close(in);#if 0 if (err < 0) { error("snd_config_load error: %s", snd_strerror(err)); return err; }#endif } if (!cardname) { int card, first = 1; card = -1; /* find each installed soundcards */ while (1) { if (snd_card_next(&card) < 0) break; if (card < 0) { if (first) { error("No soundcards found..."); return -ENODEV; } break; } first = 0; if ((err = get_controls(card, config))) return err; } } else { int cardno; cardno = snd_card_get_index(cardname); if (cardno < 0) { error("Cannot find soundcard '%s'...", cardname); return cardno; } if ((err = get_controls(cardno, config))) { return err; } } if (stdio) err = snd_output_stdio_attach(&out, stdout, 0); else err = snd_output_stdio_open(&out, file, "w"); if (err < 0) { error("Cannot open %s for writing: %s", file, snd_strerror(err)); return -errno; } err = snd_config_save(config, out); snd_output_close(out); if (err < 0) error("snd_config_save: %s", snd_strerror(err)); return 0;}int load_state(const char *file, const char *cardname){ int err; snd_config_t *config; snd_input_t *in; int stdio; err = snd_config_top(&config); if (err < 0) { error("snd_config_top error: %s", snd_strerror(err)); return err; } stdio = !strcmp(file, "-"); if (stdio) err = snd_input_stdio_attach(&in, stdin, 0); else err = snd_input_stdio_open(&in, file, "r"); if (err >= 0) { err = snd_config_load(config, in); snd_input_close(in); if (err < 0) { error("snd_config_load error: %s", snd_strerror(err)); return err; } } else { error("Cannot open %s for reading: %s", file, snd_strerror(err)); return err; } if (!cardname) { int card, first = 1; card = -1; /* find each installed soundcards */ while (1) { if (snd_card_next(&card) < 0) break; if (card < 0) { if (first) { error("No soundcards found..."); return -ENODEV; } break; } first = 0; if ((err = set_controls(card, config)) && ! force_restore) return err; } } else { int cardno; cardno = snd_card_get_index(cardname); if (cardno < 0) { error("Cannot find soundcard '%s'...", cardname); return -ENODEV; } if ((err = set_controls(cardno, config)) && ! force_restore) { return err; } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -