On 03/15/2018 02:45 PM, Takashi Sakamoto wrote:
On Mar 15 2018 21:20, Oleksandr Andrushchenko wrote:
On 03/15/2018 01:59 PM, Takashi Sakamoto wrote:
Hi,
On Mar 15 2018 19:45, Oleksandr Andrushchenko wrote:
Is it possible for user-space to reduce configuration space with snd_pcm_hw_params_set_rate_minmax and then change it with another snd_pcm_hw_params_set_rate_minmax with values out of the reduced config?
For example, the initial min/max is 44100/48000 and I set 44100 first, e.g.
snd_pcm_hw_params_set_rate_minmax(handle, hw_params, 44100, 0, 44100, 0)
and then want
snd_pcm_hw_params_set_rate_minmax(handle, hw_params, 48000, 0, 48000, 0)
Obviously, the last call fails as we have already a reduced space of [44100; 44100].
Is there a way I can still set the range to [48000; 48000]?
Thank you, Oleksandr
P.S. This is in context of work done for [1]
We can't. Once shrinking available interval of a parameter, we cannot expand it again without initializing the parameter on memory object for 'struct snd_pcm_hw_params_t', in which actual layout is never disclosed to user applications.
So, this effectively means that this is a one way road, if you need to change some parameter you'll need to start all over, so the whole configuration space remains consistent :(
You miss whole a design of ALSA PCM interface and protocol.
Probably I was not clear: by one way road I meant that if I reduce configuration space from [44100; 48000] to [44100; 44100] then there is no way to reconfigure to [48000; 48000]
The protocol consists of interactions between applications, ALSA PCM core and drivers: 1.Userspace applications are expected to allocate 'struct snd_pcm_hw_params' in its VMA, then fill it with maximum range and set of parameters. 2.The applications are expected to execute ioctl(2) with SNDRV_PCM_IOCTL_HW_REFINE, to inquire available set of parameters. 3.In kernel land, ALSA PCM core handles the ioctl request, then shrink range and set of parameters on the applications' VMA according to runtime information registered by used drivers. 4.In this time, in userspace, memory object for the 'struct snd_pcm_hw_params' represents available range and set parameters. The applications are expected to decide actual value of the parameters. If no interests, leave them as is. 5.The applications are expected to execute ioctl(2) with SNDRV_PCM_IOCTL_HW_PARAMS finally. 6.In kernel land, ALSA PCM core handles the request, then choose final range and set of parameters.
In this protocol, one way is better because expanding range and set of parameters brings ambiguity of available range and set.
No doubt here, as I am implementing a sound device driver I already know that, but thank you anyways for great description
If you can initialize whole the parameters, snd_pcm_hw_params_any() is available for your purpose, then set min/max rate again.
This is what I do now but...
But just for one of the parameters, in my opinion, we need to open an internal API; snd_pcm_hw_param_any()[1].
IMO, this will lead to the false assumption that configuration is possible. For example, I set 4 channels and 44100, but then, after snd_pcm_hw_params_any, set 48000 and might assume that the configuration is still possible. But this may not be true: it is true for the configuration returned by snd_pcm_hw_param_any as we don't know about 4 channels yet. But might not be allowed if we want 4 channels and 48000 at the same time.
Exactly. In short, it's not better idea to expand range and set of parameters during the above steps.
For your information, in runtime of PCM substream, several parameters can have dependency. Actually, to handle the dependency, SNDRV_PCM_IOCTL_HW_REFINE should be called several times to inquire available range and set of parameters to drivers which satisfies hardware specification.
Let me elaborate more on the reason of the question, so probably bigger picture allows better understanding of my problem.
Recently I pushed a patch series for Xen hypervisor para-virtualized sound [1] which aims to add a possibility for the frontend driver to negotiate HW PCM parameters with the backend, so frontend can tell the user-space that configuration is possible. Please see this discussion [2] where Takashi Iwai has provided me with great explanation on how to implement that with the use of rules in the frontend driver. This does work as expected, so I can intersect all those calls when user-space refines HW parameters. The problem is that the backend is a user-space application and whenever I pass a parameter interval from kernel driver (frontend) to the backend I only have alsalib API to refine the range. So, on backend side I see something like:
# aplay --dump-hw-params alsa/sample.wav [ frontend] --------------------- alsa_open [ backend ] snd_pcm_hw_params_any(mHwQueryHandle, mHwQueryParams)) Playing WAVE 'alsa/sample.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo ... [ frontend] rule->var 11 ret 1 min 44100 max 48000 [ backend ] snd_pcm_hw_params_set_rate_minmax(..., 44100, 0, 48000, 0) -> Ok ... [ frontend] rule->var 11 ret 0 *min 44100 max 44100* [ backend ] snd_pcm_hw_params_set_rate_minmax(..., 44100, 0, 44100, 0) -> Ok ... [ frontend] rule->var 11 ret 0 *min 48000 max 48000* [ backend ] snd_pcm_hw_params_set_rate_minmax(..., 48000, 0, 48000, 0) -> Fail
So, the last one obviously fails on backend side but still valid for the frontend. This is from where the original question came from.
Hope this clarifies my use-case.
Regards
Takashi Sakamoto
Thank you, Oleksandr Andrushchenko