[alsa-devel] Some questions about userspace control elements
Dear all,
I have some questions about ALSA control interface.
Currently I'm working for writing control applications in userspace. The application adds some control elements to a certain control device, then execute interprocess communication via the device by ALSA control interface.
To help this work, I'm preparing for alsa-gir, with partly implementation of ALSA Control/Timer/Sequencer interface. (Currently I have no plan to support the other interfaces, such as PCM.)
https://github.com/takaswie/alsa-gir
Then I have six questions.
1.The 'numid' is unique number for each element or not. 2.The 'numid' is always zero in SND_CTL_EVENT_MASK_ADD event. 3.The way to change permissions of each control element. 4.Added elements are not removed when closing fd. 5.Processes can delete elements which the other processes added. 6.The operation to replace element generates separate events.
In detail: 1.The 'numid' is unique number for each element or not? I want to use it to indicate each element, if possible. But there're more members in snd_ctl_elem_id structure.
2.The 'numid' can be notified in SND_CTL_EVENT_MASK_ADD event? As long as I test, it's always zero when userspace applications add any elements. Is it an expected behaviour? Or a bug?
3.The way to change permissions of each control element. Is it possible after adding the elements? If possible, how to notify it in the other processes?
4.Any elements added by a process are not removed at closing snd_ctl_t. They're remained after closing the process' snd_ctl_t. Is it an expected behaviour? Or a bug?
5.Processes can delete elements which the other processes added. Is it an expected behaviour? Or a bug?
6.The operation to replace elements generates separate events. ADD/REMOVE events occurs sequencially. Userspace application cannot distinguish replacement from adding/removing, therefore cannot process appropriate action. Is it an expected behaviour? Or a bug?
Regards
Takashi Sakamoto
Takashi Sakamoto wrote:
1.The 'numid' is unique number for each element or not? I want to use it to indicate each element, if possible. But there're more members in snd_ctl_elem_id structure.
The other members help with searching elements. But numid itself must be unique.
2.The 'numid' can be notified in SND_CTL_EVENT_MASK_ADD event? As long as I test, it's always zero when userspace applications add any elements. Is it an expected behaviour? Or a bug?
This looks like a bug in the kernel code.
All the other members of the id structure should be correct; as a workaround, try calling snd_ctl_elem_info().
3.The way to change permissions of each control element. Is it possible after adding the elements? If possible, how to notify it in the other processes?
At the moment, this is not possible for userspace controls.
What bit(s) do you want to change?
4.Any elements added by a process are not removed at closing snd_ctl_t. They're remained after closing the process' snd_ctl_t. Is it an expected behaviour? Or a bug?
This is by design. These controls are intended to be a property of the device itself, and to be somewhat permanent.
5.Processes can delete elements which the other processes added. Is it an expected behaviour? Or a bug?
For permanent controls, it would not be possible to remember which process created them originally.
6.The operation to replace elements generates separate events. ADD/REMOVE events occurs sequencially. Userspace application cannot distinguish replacement from adding/removing, therefore cannot process appropriate action. Is it an expected behaviour? Or a bug?
Replacement is just a shortcut for removing/adding. So far, changing the properties of userspace controls has not been necessary.
Regards, Clemens
Hi Clemens,
Thanks for your answer. I want to discuss about the design of ALSA userspace controls with you, while today I've read some related kernel codes and realized they're more buggy than I expected...perhaps. I'd like to start discussion after fixing them.
Thanks
Takashi Sakamoto
On Feb 2 2015 02:50, Clemens Ladisch wrote:
Takashi Sakamoto wrote:
1.The 'numid' is unique number for each element or not? I want to use it to indicate each element, if possible. But there're more members in snd_ctl_elem_id structure.
The other members help with searching elements. But numid itself must be unique.
2.The 'numid' can be notified in SND_CTL_EVENT_MASK_ADD event? As long as I test, it's always zero when userspace applications add any elements. Is it an expected behaviour? Or a bug?
This looks like a bug in the kernel code.
All the other members of the id structure should be correct; as a workaround, try calling snd_ctl_elem_info().
3.The way to change permissions of each control element. Is it possible after adding the elements? If possible, how to notify it in the other processes?
At the moment, this is not possible for userspace controls.
What bit(s) do you want to change?
4.Any elements added by a process are not removed at closing snd_ctl_t. They're remained after closing the process' snd_ctl_t. Is it an expected behaviour? Or a bug?
This is by design. These controls are intended to be a property of the device itself, and to be somewhat permanent.
5.Processes can delete elements which the other processes added. Is it an expected behaviour? Or a bug?
For permanent controls, it would not be possible to remember which process created them originally.
6.The operation to replace elements generates separate events. ADD/REMOVE events occurs sequencially. Userspace application cannot distinguish replacement from adding/removing, therefore cannot process appropriate action. Is it an expected behaviour? Or a bug?
Replacement is just a shortcut for removing/adding. So far, changing the properties of userspace controls has not been necessary.
Regards, Clemens
Hi Clemens,
I find a curious issue about the userspace element. Could I ask you to give some comments about
The code is this one line.
sound/core/control.c:1188 {{{ kctl.count = info->owner ? info->owner : 1; }}} http://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/tree/sound/core/...
In this code, the value in struct snd_ctl_elem_info.owner is assigned to struct snd_kcontrol.count. The meaning of these two member is completely different but assigned.
include/sound/control.h:67 {{{ struct snd_kcontrol { ... unsigned int count; ... }; }}} http://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/tree/include/sou...
include/uapi/sound/asound.h:851 {{{ struct snd_ctl_elem_info { ... __kernel_pid_t owner; /* owner's PID of this control */ ... }; }; }}} http://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/tree/include/uap... (I wonder why the value with _kernel_pid type is exported to userspace...)
I guess that the reason is to limit the number of event generated when the control element set is operated. Actually, my sample code reports one event every time when operating the control element with 10 entries. But I believe this is the different behaviour as the kernel control elements do.
sound/core/control.c:257 {{{ kctl.count = ncontrol->count ? ncontrol->count : 1; }}} http://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/tree/sound/core/...
For me, the behaviour of userspace control element is a bit strange. The behaviour is legal as a control element?
Regards
Takashi Sakamoto
I want to add some supplement to my previous message. (sorry to include some logic jump...)
On Feb 5 2015 08:51, Takashi Sakamoto wrote:
The code is this one line.
sound/core/control.c:1188 {{{ kctl.count = info->owner ? info->owner : 1; }}} http://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/tree/sound/core/...
In this code, the value in struct snd_ctl_elem_info.owner is assigned to struct snd_kcontrol.count. The meaning of these two member is completely different but assigned.
When any userspace control element are added, the value of struct snd_ctl_elem_info.owner is zero because there's no API to set this member in userspace and snd_ctl_elem_info_alloca() or snd_ctl_elem_info_malloc() initialize allocated memory with zero.
Then, 1 is always assigned to the kctl.count.
I guess that the reason is to limit the number of event generated when the control element set is operated. Actually, my sample code reports one event every time when operating the control element with 10 entries. But I believe this is the different behaviour as the kernel control elements do.
For example, 'add' event is generated in sound/core/contro.c:378. This event is generated several times as the number of count: http://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/tree/sound/core/...
Due to kctl.count is assigned to 1, the number of generated event for userspace control elements is one time.
sound/core/control.c:257 {{{ kctl.count = ncontrol->count ? ncontrol->count : 1; }}} http://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/tree/sound/core/...
For me, the behaviour of userspace control element is a bit strange. The behaviour is legal as a control element?
On the other hand, in kernel control element, kctl.count is assigned to the value which each driver gives. Therefore, the number of generated events is the same as the number of element count.
In these reasons, the number of generated events is different between kernel/userspace control element.
Actually, there's a few kernel control elements in which the number of count is bigger than 1. So in most case, users cannot realize the differences to use ALSA control application such as alsamixer. The behaviour of userspace control elements looks like kernel control elements which major sound drivers give.
Please inform to me if my understanding is wrong.
Regards
Takashi Sakamoto
Takashi Sakamoto wrote:
On Feb 5 2015 08:51, Takashi Sakamoto wrote:
sound/core/control.c:1188 {{{ kctl.count = info->owner ? info->owner : 1; }}}
In this code, the value in struct snd_ctl_elem_info.owner is assigned to struct snd_kcontrol.count. The meaning of these two member is completely different but assigned.
There is hardware that has many identical controls. To save memory, ALSA treats controls with .count > 1 as if there were multiple controls.
This optimization is not visible in the userspace API.
The owner field is used because there is no other field to set the count.
When any userspace control element are added, the value of struct snd_ctl_elem_info.owner is zero because there's no API to set this member in userspace
So far, setting this field has not been needed. An API could be added.
I guess that the reason is to limit the number of event generated when the control element set is operated.
If a driver needs twenty identical controls, it could create one control with count=20, or twenty controls with count=1. In both cases, twenty events are sent.
Regards, Clemens
Hi Clemens,
On Feb 6 2015 18:38, Clemens Ladisch wrote:
Takashi Sakamoto wrote:
On Feb 5 2015 08:51, Takashi Sakamoto wrote:
sound/core/control.c:1188 {{{ kctl.count = info->owner ? info->owner : 1; }}}
In this code, the value in struct snd_ctl_elem_info.owner is assigned to struct snd_kcontrol.count. The meaning of these two member is completely different but assigned.
There is hardware that has many identhtical controls. To save memory, ALSA treats controls with .count > 1 as if there were multiple controls.
This optimization is not visible in the userspace API.
In my understanding, it's due to the granularity of operation. If we assume a PCI device has one register to express several control elements as bitfield. One read or write operation can handle these controls. Such control elements can be expressed in one ALSA control substance.
The owner field is used because there is no other field to set the count.
No. In SNDRV_CTL_IOCTL_ELEM_ADD ioctl, struct snd_ctl_elem_info.count has the number of elements in this control, there it's an abuse of member unrelated to the count.
When any userspace control element are added, the value of struct snd_ctl_elem_info.owner is zero because there's no API to set this member in userspace
So far, setting this field has not been needed. An API could be added.
I cannot find the advantage to add such API in userspace. The value of owner field SHOULD be set just by lock/unlock API.
I guess that the reason is to limit the number of event generated when the control element set is operated.
If a driver needs twenty identical controls, it could create one control with count=20, or twenty controls with count=1. In both cases, twenty events are sent.
But this is not applied to userspace controls because a control with 20 elements can generate one events instead of 20.
This is ugly because it demands userspace applications to distinguish kernel/userspace application in event handling.
Thanks
Takashi Sakamoto
Takashi Sakamoto wrote:
On Feb 6 2015 18:38, Clemens Ladisch wrote:
The owner field is used because there is no other field to set the count.
No. In SNDRV_CTL_IOCTL_ELEM_ADD ioctl, struct snd_ctl_elem_info.count has the number of elements in this control, there it's an abuse of member unrelated to the count.
That is a different count.
struct snd_ctl_elem_info.count allows a control to have multiple values. For example, a stereo volume control has two values.
kctl.count creates multiple controls.
Regards, Clemens
On Feb 8 2014 00:45, Clemens Ladisch wrote:
Takashi Sakamoto wrote:
On Feb 6 2015 18:38, Clemens Ladisch wrote:
The owner field is used because there is no other field to set the count.
No. In SNDRV_CTL_IOCTL_ELEM_ADD ioctl, struct snd_ctl_elem_info.count has the number of elements in this control, there it's an abuse of member unrelated to the count.
That is a different count.
struct snd_ctl_elem_info.count allows a control to have multiple values. For example, a stereo volume control has two values.
kctl.count creates multiple controls.
Oh, I confused these two 'count's... I'm OK that the count member in struct snd_kcontrol means the number of controls (elements) with the same type, and the count member in struct snd_ctl_elem_info means the number of values in a controls, then the event occurs every controls, not for values.
Thanks
Takashi Sakamoto
participants (2)
-
Clemens Ladisch
-
Takashi Sakamoto