alsa-project / alsa-lib

The Advanced Linux Sound Architecture (ALSA) - library
GNU Lesser General Public License v2.1
344 stars 173 forks source link

External I/O-Plugin API is missing precise timestamp control #377

Open z-s-e opened 6 months ago

z-s-e commented 6 months ago

Unless I overlooked something, it seems not possible for an ioplug plugin to influence the timestamps reported by snd_pcm_status_get_htstamp() - I suppose those are rather autogenerated by the lib and thus of fairly low precision. Also, at the moment it is possible that a status update contains newer timestamps than a previous update, but without an increased snd_pcm_status_get_avail() value, which makes these autogenerated timestamps not very well behaved.

It would be much better if there was a way for a plugin to tell the alsa-lib which timestamps it should forward to the user.

perexg commented 6 months ago

I miss what you suggest. The ioplug interface cannot be precise by design.

z-s-e commented 6 months ago

What do you mean by "it cannot be precise by design"? As far as I can see, a simple addition to the plugin api (for compatibility of course an opt-in) to allow an alternate callback that can report avail and timestamp values that belong together seems to be all that is needed for allowing similar precision to any other backend.

perexg commented 6 months ago

I mean atomicity for hw_ptr (avail) + timestamp updates. Unless we have a real use (external plugin) providing timestamps, this extension in alsa-lib is not necessary.

The note about snd_pcm_status_get_avail() is also invalid. If you see snd_pcm_ioplug_status(), the hw_ptr is updated and then the timestamp is fetched. It depends on granularity of the ring buffer pointer updates for specific external plugin.

Note that timestamp means "when the ring buffer pointer" was updated. It is not any prediction where the pointer should be at the real time. The application may calculate this on own using the system's real time clock.

z-s-e commented 6 months ago

I'm not quite sure I understand your arguments. Here is my motivation for this; as an application developer it would be nice if I could just use the alsa API and have good results regardless of whether the device used is a hw or a ioplug one. And since 99% of the Linux desktops are running sound servers like pulseaudio or pipewire, the ioplug use case is very important.

But if ioplug will remain "second class" like this, it forces app developers to write alternate backends to target the sound server's native APIs, multiplying the needed effort needlessly. So I believe fixing this would be not only good for me but more generally for the Linux ecosystem (once the sound server's ioplug adapters would adopt this improvement of course). Or do you not see alsa as such a unifying API?

I did have a quick look at snd_pcm_ioplug_status(). One possible small improvement over the status quo (afaiu) may be to not just always generate new timestamps, but only when in snd_pcm_ioplug_hw_ptr_update the new hw pointer actually changed (so generate a new timestamp when hw != io->last_hw, otherwise reuse a previous one (which would of course need to be buffered somewhere)). That wouldn't require new API, but of course wouldn't really solve the issue fully.

perexg commented 5 months ago

I'm not quite sure I understand your arguments. Here is my motivation for this; as an application developer it would be nice if I could just use the alsa API and have good results regardless of whether the device used is a hw or a ioplug one. And since 99% of the Linux desktops are running sound servers like pulseaudio or pipewire, the ioplug use case is very important.

I don't think that PA/PW provides any precise timestamping, but I might be wrong. If they have this in their APIs, I'm not against plugio extension, but if the change is useless, why bother?

I did have a quick look at snd_pcm_ioplug_status(). One possible small improvement over the status quo (afaiu) may be to not just always generate new timestamps, but only when in snd_pcm_ioplug_hw_ptr_update the new hw pointer actually changed (so generate a new timestamp when hw != io->last_hw, otherwise reuse a previous one (which would of course need to be buffered somewhere)). That wouldn't require new API, but of course wouldn't really solve the issue fully.

Yes, timestamps may be updated only when hw_ptr changes not when status is called. But in this way, the timestamping may be done more often (syscalls), thus eating more CPU ticks.

z-s-e commented 5 months ago

I don't think that PA/PW provides any precise timestamping, but I might be wrong. If they have this in their APIs, I'm not against plugio extension, but if the change is useless, why bother?

Both PA and PW have API to provide timestamps similar to alsa. I have not personally verified the accuracy of the timing info they provide, but since good timing info is important for e.g. audio-video synchronization I would assume they are on the same level as alsa.

Anyway, I understand not being motivated when I'm the only one bothered by it, so I won't push this further for now. Maybe in the future I might propose a patch myself... I'll leave it to you whether you want to close this issue for now or leave it open as a reminder.

perexg commented 5 months ago

PA have different timestamps: "The returned time is in the sound card clock domain, which usually runs at a slightly different rate than the system clock.". So PA is ruled out.

PW timestamps are fine for monotonic timestamp (based on CLOCK_MONOTONIC - clock_gettime) so for other types we need to covert the values between time domains which may not be easy and less accurate (probably using time differences).

z-s-e commented 5 months ago

PA also have system clock timestamps, see here. Personally I'm not sure why anyone would ever use anything other than CLOCK_MONOTONIC, so I'd be fine with only supporting that.

perexg commented 5 months ago

I don't see the time domain there.

tiwai commented 5 months ago

The extension of alsa-lib ioplug API itself should be easy, something trivial like below. 0001-pcm-ioplug-Add-timestamp-support.patch.txt

Or do we need more other stuff?

z-s-e commented 5 months ago

Yes, afaics that should be sufficient.