On Fri, Jul 12, 2024 at 06:48:09PM +0900, Asahi Lina wrote: > > For example, assuming the matrix mixer has 34 destination and 66 > > sources, they can be expressed by 34 control elements with 66 array > > elements. A single snd_kcontrol structure can provide them, as long as > > they have the same nature. The control elements are identified by index > > value. > > It took me a while to understand what you meant here, but I think I get > it: Using a single snd_kcontrol for the entire mixer, with 34 indexed > elements each taking 66 array values, right? This is rough example for the above idea. ``` static int info_cb(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *einfo) { einfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; einfo->count = 66; // up to 128 for integer value array. einfo->value.integer.min = 0; // note long type, varies between // ILP32/LP64 data models. einfo->value.integer.max = 256; // ditto. einfo->value.integer.step = 1; // ditto. return 0; } static int get_cb(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uval) { unsigned int index = snd_ctl_get_ioff(kctl, &info->id); // Any operation according to the index of control elements in the set. return 0; } static int put_cb(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uval) { unsigned int offset = snd_ctl_get_ioff(kctl, &info->id); // Any operation according to the index of control elements in the set. return 0; } int add_control_elements(struct my_data *my_data) { // Emulate AK4396. // 20 * log10(x/255) (dB) // Here, x is written value. // // Some examples in: // https://github.com/alsa-project/alsa-lib/blob/master/test/user-ctl-element-set.c. static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(range_tlv, -4813, 0); static const struct snd_kcontrol_new template = { . iface = SNDRV_CTL_ELEM_IFACE_MIXER, .device = 10, .subdevice = 20, .name = "multiplexer", .index = 0, // I guess any operation on ARC USB does not control the hardware directly unlike RC and // ARC, thus SNDRV_CTL_ELEM_ACCESS_VOLATILE is not required. .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, .count = 34, // The total number of control elements in the set. .info = info_cb, .get = get_cb, .put = pub_cb, .tlv.p = &range_tlv, }; struct snd_kcontrol *kctl = snd_ctl_new1(&template, my_data); err = snd_ctl_add(my_data->card, kctl); ... } ``` > How do these kinds of controls show up in alsamixer and other userspace > mixer tools? Are they usable at all, or just with low-level access via > amixer/alsactl? These control elements can be enumerated and operated as usual, just have the sequential value in index (and numid) field in element identifier. ``` $ amixer -c 0 controls ... numid=16,iface=MIXER,name='multiplexer',device=10,subdevice=20 numid=17,iface=MIXER,name='multiplexer',index=1,device=10,subdevice=20 numid=18,iface=MIXER,name='multiplexer',index=2,device=10,subdevice=20 numid=19,iface=MIXER,name='multiplexer',index=3,device=10,subdevice=20 numid=20,iface=MIXER,name='multiplexer',index=4,device=10,subdevice=20 numid=21,iface=MIXER,name='multiplexer',index=5,device=10,subdevice=20 numid=22,iface=MIXER,name='multiplexer',index=6,device=10,subdevice=20 numid=23,iface=MIXER,name='multiplexer',index=7,device=10,subdevice=20 numid=24,iface=MIXER,name='multiplexer',index=8,device=10,subdevice=20 numid=25,iface=MIXER,name='multiplexer',index=9,device=10,subdevice=20 ... ``` Of cource, these is no integrations in any type of alsa-lib mixer API abstractions. I use Quasmixer in quastools project to operate them. * https://gitlab.com/sebholt/qastools Regards Takashi Sakamoto