Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No way to get notified of playback progress #54

Closed
ghost opened this issue May 31, 2020 · 5 comments
Closed

No way to get notified of playback progress #54

ghost opened this issue May 31, 2020 · 5 comments

Comments

@ghost
Copy link

ghost commented May 31, 2020

See subject. There is a way to run user code in a signal handler with snd_async_add_pcm_handler(). But that seems extremely questionable, is for sure not supported everywhere, and is probably full of subtle synchronization bugs. There is snd_pcm_poll_descriptors() and related, but that seems to signal only whether at least 1 period is available, nothing else. Judging from the docs.

That seems like a rather big missing thing - I probably overlooked something. Otherwise this is a feature request for an asynchronous notification on period boundaries/underruns/device disconnection, that does not run in a UNIX signal handler. Maybe something relatively similar to that poll() mechanism.

@perexg
Copy link
Member

perexg commented Jun 3, 2020

The snd_pcm_avail_update() can be called at any time, so you don't need to rely on period boundary. It's just your response, how you design your app. The period timing is based on how the most hardware works, but ALSA API does not force to use it. Do you need other timing? Just use it and monitor the buffer position.

@perexg perexg closed this as completed Jun 3, 2020
@ghost
Copy link
Author

ghost commented Jun 3, 2020

Yes, I can poll, but that isn't enough. If I poll in regular intervals, I have to 1) assume that audio goes about as fast as system time (whatever clock I use for polling), and 2) have to poll more often than theoretically necessary, because in practice assumption 1) is wrong, and it's easy to miss the period event.

What I actually want is:

  • an event on which I should refill the audio buffer (prerably for optimal low latency without being susceptible for underruns)
  • know when the last bit of audio was played (equivalent to an intentional XRUN I guess)

I just thought a period boundary event would be the ideal way to achieve this. For the first item, using poll() and requesting a low number of periods would probably be sufficient. The signal handler is a nice idea, but not really workable I guess, except maybe for special applications.

@perexg
Copy link
Member

perexg commented Jun 3, 2020

The poll wake up thresholds can be controlled using sw_params (avail variable). But the resolution is period based, of course.

@ghost
Copy link
Author

ghost commented Jun 3, 2020

That's interesting. I see snd_pcm_sw_params_set_avail_min() and snd_pcm_sw_params_set_period_event(). But it's not really clear how exactly they behave or how to use them. Is "PCM ready" equivalent to the poll FD being set to writable? What is a poll wakeup event? Is it edge or level triggered? When exactly these events happen is not clear either.

@perexg
Copy link
Member

perexg commented Jun 4, 2020

Everything is poll() related. The period event is trigger based (each period boundary), the avail threshold is level based. If the application does not update the ring buffer pointer using snd_pcm_avail_update() or snd_pcm_status(), then the driver updates position only at period boundaries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant