Functionality of pcm_notify in snd-aloop?
Hi,
Please how is the module params pcm_notify supposed to be used, to do what the documentation says: Break capture when PCM format/rate/channels changes?
Breaking capture side operation when the playback side changes the params is very useful, but I cannot find a way to use this param properly. When the capture side is open, the playback side cannot use a different parameter than the one currently used by the capture side (the configuration space is limited) - how can the param be changed then?
Thanks a lot for help.
Best regards,
Pavel.
Dne 26. 03. 20 v 18:19 Pavel Hofman napsal(a):
Hi,
Please how is the module params pcm_notify supposed to be used, to do what the documentation says: Break capture when PCM format/rate/channels changes?
Breaking capture side operation when the playback side changes the params is very useful, but I cannot find a way to use this param properly. When the capture side is open, the playback side cannot use a different parameter than the one currently used by the capture side (the configuration space is limited)
Really? Then it's a bug introduced by the last changes.
If you look to sources:
if (get_notify(dpcm)) runtime->hw = loopback_pcm_hardware; else runtime->hw = cable->hw;
And:
if (!(cable->valid & ~(1 << substream->stream)) || (get_setup(dpcm)->notify && substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) params_change(substream);
So the functionality should be there.
Jaroslav
Dne 26. 03. 20 v 18:44 Jaroslav Kysela napsal(a):
Dne 26. 03. 20 v 18:19 Pavel Hofman napsal(a):
Hi,
Please how is the module params pcm_notify supposed to be used, to do what the documentation says: Break capture when PCM format/rate/channels changes?
Breaking capture side operation when the playback side changes the params is very useful, but I cannot find a way to use this param properly. When the capture side is open, the playback side cannot use a different parameter than the one currently used by the capture side (the configuration space is limited)
Really? Then it's a bug introduced by the last changes.
If you look to sources:
if (get_notify(dpcm)) runtime->hw = loopback_pcm_hardware; else runtime->hw = cable->hw;
And:
if (!(cable->valid & ~(1 << substream->stream)) || (get_setup(dpcm)->notify && substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) params_change(substream);
So the functionality should be there.
I am using older kernels (4.15 and 3.16), but this is an old functionality.
modprobe snd-aloop pcm_substreams=1 pcm_notify=1,1
Playback with no capture
aplay -v --dump-hw-params -D hw:0,0 -r 48000 -c 2 -f S32_LE /dev/zero Přehrávám syrová data '/dev/zero' : Signed 32 bit Little Endian, Frekvence 48000 Hz, Stereo HW Params of device "hw:0,0": -------------------- ACCESS: MMAP_INTERLEAVED RW_INTERLEAVED FORMAT: S16_LE S16_BE S32_LE S32_BE FLOAT_LE FLOAT_BE SUBFORMAT: STD SAMPLE_BITS: [16 32] FRAME_BITS: [16 1024] CHANNELS: [1 32] RATE: [8000 19200000] PERIOD_TIME: (0 65536000] PERIOD_SIZE: [1 524288] PERIOD_BYTES: [64 1048576] PERIODS: [1 1024] BUFFER_TIME: (0 524288000] BUFFER_SIZE: [1 4194304] BUFFER_BYTES: [64 8388608]
Playback with capture running (arecord at 48000):
aplay -v --dump-hw-params -D hw:0,0 -r 96000 -c 2 -f S32_LE /dev/zero Playing raw data '/dev/zero' : Signed 32 bit Little Endian, Rate 96000 Hz, Stereo HW Params of device "hw:0,0": -------------------- ACCESS: MMAP_INTERLEAVED RW_INTERLEAVED FORMAT: S32_LE SUBFORMAT: STD SAMPLE_BITS: 32 FRAME_BITS: 64 CHANNELS: 2 RATE: 48000 PERIOD_TIME: (166 2730667) PERIOD_SIZE: [8 131072] PERIOD_BYTES: [64 1048576] PERIODS: [1 1024] BUFFER_TIME: (166 21845334) BUFFER_SIZE: [8 1048576] BUFFER_BYTES: [64 8388608] TICK_TIME: ALL -------------------- Warning: rate is not accurate (requested = 96000Hz, got = 48000Hz) please, try the plug plugin
Thanks a lot.
Pavel.
Dne 26. 03. 20 v 18:59 Pavel Hofman napsal(a):
Dne 26. 03. 20 v 18:44 Jaroslav Kysela napsal(a):
Dne 26. 03. 20 v 18:19 Pavel Hofman napsal(a):
Hi,
Please how is the module params pcm_notify supposed to be used, to do what the documentation says: Break capture when PCM format/rate/channels changes?
Breaking capture side operation when the playback side changes the params is very useful, but I cannot find a way to use this param properly. When the capture side is open, the playback side cannot use a different parameter than the one currently used by the capture side (the configuration space is limited)
Really? Then it's a bug introduced by the last changes.
If you look to sources:
if (get_notify(dpcm)) runtime->hw = loopback_pcm_hardware; else runtime->hw = cable->hw;
And:
if (!(cable->valid & ~(1 << substream->stream)) || (get_setup(dpcm)->notify && substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) params_change(substream);
So the functionality should be there.
I am using older kernels (4.15 and 3.16), but this is an old functionality.
modprobe snd-aloop pcm_substreams=1 pcm_notify=1,1
Please is there any way to solve this issue? Thanks a lot for your patience.
Best regards,
Pavel.
Dne 30. 03. 20 v 16:43 Pavel Hofman napsal(a):
Dne 26. 03. 20 v 18:59 Pavel Hofman napsal(a):
Dne 26. 03. 20 v 18:44 Jaroslav Kysela napsal(a):
Dne 26. 03. 20 v 18:19 Pavel Hofman napsal(a):
Hi,
Please how is the module params pcm_notify supposed to be used, to do what the documentation says: Break capture when PCM format/rate/channels changes?
Breaking capture side operation when the playback side changes the params is very useful, but I cannot find a way to use this param properly. When the capture side is open, the playback side cannot use a different parameter than the one currently used by the capture side (the configuration space is limited)
Really? Then it's a bug introduced by the last changes.
If you look to sources:
if (get_notify(dpcm)) runtime->hw = loopback_pcm_hardware; else runtime->hw = cable->hw;
And:
if (!(cable->valid & ~(1 << substream->stream)) || (get_setup(dpcm)->notify && substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) params_change(substream);
So the functionality should be there.
I am using older kernels (4.15 and 3.16), but this is an old functionality.
modprobe snd-aloop pcm_substreams=1 pcm_notify=1,1
Please is there any way to solve this issue? Thanks a lot for your patience.
I can reproduce this. It appears that the driver should be fixed, but I don't have a solution at the moment.
It seems that 898dfe4687f460ba337a01c11549f87269a13fa2 from Takashi broke this functionality (tied the cable parameters more strictly, so the playback cannot set freely own parameters for the pcm_notify=1 case). We need to find another way to detach capture stream in this case.
Jaroslav
Dne 30. 03. 20 v 17:09 Jaroslav Kysela napsal(a):
Dne 30. 03. 20 v 16:43 Pavel Hofman napsal(a):
Dne 26. 03. 20 v 18:59 Pavel Hofman napsal(a):
Dne 26. 03. 20 v 18:44 Jaroslav Kysela napsal(a):
Dne 26. 03. 20 v 18:19 Pavel Hofman napsal(a):
Hi,
Please how is the module params pcm_notify supposed to be used, to do what the documentation says: Break capture when PCM format/rate/channels changes?
Breaking capture side operation when the playback side changes the params is very useful, but I cannot find a way to use this param properly. When the capture side is open, the playback side cannot use a different parameter than the one currently used by the capture side (the configuration space is limited)
Really? Then it's a bug introduced by the last changes.
If you look to sources:
if (get_notify(dpcm)) runtime->hw = loopback_pcm_hardware; else runtime->hw = cable->hw;
And:
if (!(cable->valid & ~(1 << substream->stream)) || (get_setup(dpcm)->notify && substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) params_change(substream);
So the functionality should be there.
I am using older kernels (4.15 and 3.16), but this is an old functionality.
modprobe snd-aloop pcm_substreams=1 pcm_notify=1,1
Please is there any way to solve this issue? Thanks a lot for your patience.
I can reproduce this. It appears that the driver should be fixed, but I don't have a solution at the moment.
It seems that 898dfe4687f460ba337a01c11549f87269a13fa2 from Takashi broke this functionality (tied the cable parameters more strictly, so the playback cannot set freely own parameters for the pcm_notify=1 case). We need to find another way to detach capture stream in this case.
Thanks a lot for your effort. I am afraid I cannot help with such design-level task.
BTW the sound design of snd-aloop allows reliable operation at 20MHz samplerate, it took just a period_max param change https://www.diyaudio.com/forums/equipment-and-tools/349239-support-samplerat... I will ask for considering a substantial samplerate range extension in a separate post :-)
Thanks again.
Best regards,
Pavel.
On Mon, 30 Mar 2020 17:09:58 +0200, Jaroslav Kysela wrote:
Dne 30. 03. 20 v 16:43 Pavel Hofman napsal(a):
Dne 26. 03. 20 v 18:59 Pavel Hofman napsal(a):
Dne 26. 03. 20 v 18:44 Jaroslav Kysela napsal(a):
Dne 26. 03. 20 v 18:19 Pavel Hofman napsal(a):
Hi,
Please how is the module params pcm_notify supposed to be used, to do what the documentation says: Break capture when PCM format/rate/channels changes?
Breaking capture side operation when the playback side changes the params is very useful, but I cannot find a way to use this param properly. When the capture side is open, the playback side cannot use a different parameter than the one currently used by the capture side (the configuration space is limited)
Really? Then it's a bug introduced by the last changes.
If you look to sources:
if (get_notify(dpcm)) runtime->hw = loopback_pcm_hardware; else runtime->hw = cable->hw;
And:
if (!(cable->valid & ~(1 << substream->stream)) || (get_setup(dpcm)->notify && substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) params_change(substream);
So the functionality should be there.
I am using older kernels (4.15 and 3.16), but this is an old functionality.
modprobe snd-aloop pcm_substreams=1 pcm_notify=1,1
Please is there any way to solve this issue? Thanks a lot for your patience.
I can reproduce this. It appears that the driver should be fixed, but I don't have a solution at the moment.
It seems that 898dfe4687f460ba337a01c11549f87269a13fa2 from Takashi broke this functionality (tied the cable parameters more strictly, so the playback cannot set freely own parameters for the pcm_notify=1 case). We need to find another way to detach capture stream in this case.
I believe the missing piece here is a generic way to tell user-space that the stream got invalidated. This would be useful not only for aloop but can be applied in general when a stream becomes temporarily unavailable (e.g. the HDMI monitor disconnected or the DSP route switched).
Currently we may return -EPIPE for xrun, but this doesn't really tell the situation correctly. The xrun should be recoverable by simple PREPARE call, but the case like aloop would need the complete re-setup or reopen of the stream.
thanks,
Takashi
Hey,
On Tue, 28 Apr 2020, Takashi Iwai wrote:
I believe the missing piece here is a generic way to tell user-space that the stream got invalidated. This would be useful not only for aloop but can be applied in general when a stream becomes temporarily unavailable (e.g. the HDMI monitor disconnected or the DSP route switched).
ack on that. I've been preparing this patch to add -ENODATA to alsa-lib documentation: "[RFC] pcm: add documentation for -ENODATA error code handling" https://github.com/kv2019i/alsa-lib/commit/87b298106e04054489ee93b26a610e37f...
Have not yet had time to send a proper version to the list, but it's addressing specifically this need. This would serve as the interface for SOF DSP to tell that a given PCM node will not be providing data (as the DSP topology is not fully connected) [1].
To test the above, I've used a small hack to aplay/arecord that keeps trying to restart the PCM after a delay, in case -ENODATA is returned: https://github.com/kv2019i/alsa-utils/commit/a2ba541ea0b3e86a65687de88a41f10...
[1] https://github.com/thesofproject/sof/issues/2564
Br, Kai
Dne 28. 04. 20 v 18:19 Kai Vehmanen napsal(a):
Hey,
On Tue, 28 Apr 2020, Takashi Iwai wrote:
I believe the missing piece here is a generic way to tell user-space that the stream got invalidated. This would be useful not only for aloop but can be applied in general when a stream becomes temporarily unavailable (e.g. the HDMI monitor disconnected or the DSP route switched).
ack on that. I've been preparing this patch to add -ENODATA to alsa-lib documentation: "[RFC] pcm: add documentation for -ENODATA error code handling" https://github.com/kv2019i/alsa-lib/commit/87b298106e04054489ee93b26a610e37f...
Have not yet had time to send a proper version to the list, but it's addressing specifically this need. This would serve as the interface for SOF DSP to tell that a given PCM node will not be providing data (as the DSP topology is not fully connected) [1].
To test the above, I've used a small hack to aplay/arecord that keeps trying to restart the PCM after a delay, in case -ENODATA is returned: https://github.com/kv2019i/alsa-utils/commit/a2ba541ea0b3e86a65687de88a41f10...
This code calls wrongly snd_pcm_resume() here. Also, we should really think about the whole mechanism when the stream cannot be activated (also for playback - Intel HDMI LPE driver [2]). I mean that the poll multiplexer should handle this state, too. If we don't find a way to notify the user space that the stream can be started using the poll(), we can use another interface like control API for the notifications.
We may also instroduce a new PCM state "WAIT" to wait on the hardware / link availability (SETUP -> -ENODATA -> WAIT -> use poll() for the link status -> success -> SETUP -> PREPARE) - talking about SNDRV_PCM_STATE states here.
Jaroslav
[2] https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/blob/36a4923f9bd05d4c...
Hey,
On Thu, 30 Apr 2020, Jaroslav Kysela wrote:
Dne 28. 04. 20 v 18:19 Kai Vehmanen napsal(a):
ack on that. I've been preparing this patch to add -ENODATA to alsa-lib documentation: "[RFC] pcm: add documentation for -ENODATA error code handling" https://github.com/kv2019i/alsa-lib/commit/87b298106e04054489ee93b26a610e37f...
[...]
To test the above, I've used a small hack to aplay/arecord that keeps trying to restart the PCM after a delay, in case -ENODATA is returned: https://github.com/kv2019i/alsa-utils/commit/a2ba541ea0b3e86a65687de88a41f10...
This code calls wrongly snd_pcm_resume() here. Also, we should really think about the whole mechanism when the stream cannot be activated (also for playback - Intel HDMI LPE driver [2]). I mean that the poll multiplexer should handle this state, too. If we don't find a way to notify the user space that the stream can be started using the poll(), we can use another interface like control API for the notifications.
yes, the above patch for alsa-utils is just a hack for testing (I used snd_pcm_resume() as that has retry-after-delay logic already so does what I need to restart after -ENODATA).
That's a good question whether ALSA should provide a mechanism to wait and/or signal when the stream can be started.
This is not clear in the generic case. There can be scenarios where the -ENODATA state is not transient (e.g. a monitor is not connected). So the application has to have some out-of-band information on how the device behaves -- i.e. when it makes sense to wait. For the DSP echo reference case, we are now proposing to describe this in UCM, so applications (like Pulseaudio and CRAS) can get this information from there.
For many related scenarios, we are already successfully using controls to inform user-space that a given PCM is ready for use (newer drivers use this for HDMI monitor hotplug).
But it's true, even if application knows in which order to trigger the PCMs and how they are dependent, some retry logic needs to be used (especially around xrun/suspend handling). In my test code, I just simply used a delay-and-retry in the slave arecord instance, but a real-life application would use something more deterministic.
We may also instroduce a new PCM state "WAIT" to wait on the hardware / link availability (SETUP -> -ENODATA -> WAIT -> use poll() for the link status -> success -> SETUP -> PREPARE) - talking about SNDRV_PCM_STATE states here.
This could be cleaner, but a much bigger change (for applications, alsa-lib and drivers as well). Considering this is quite niche and majority of apps won't care, having applications handle -ENODATA with out-of-band means might still be the right-sized solution. At least the CRAS developer feedback so far has been that -ENODATA is sufficient.
But yeah, if there are other users/scenarios that need to wait on link-availability, maybe adding it to ALSA API directly, might make sense.
Br, Kai
participants (4)
-
Jaroslav Kysela
-
Kai Vehmanen
-
Pavel Hofman
-
Takashi Iwai