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

ALSA: Pa_GetStreamTime() is not advancing for PulseAudio #586

Open
philburk opened this issue May 27, 2021 · 9 comments
Open

ALSA: Pa_GetStreamTime() is not advancing for PulseAudio #586

philburk opened this issue May 27, 2021 · 9 comments
Labels
bug Something isn't working P3 Priority: Normal src-alsa ALSA Host API /src/hostapi/alsa

Comments

@philburk
Copy link
Collaborator

Describe the bug
Pa_GetStreamTime() always returns zero.

To Reproduce
The patest_sine_time.c test has been updated so it times out.
Use the version in #585

  1. ./configure && make
  2. bin/patest_sine_time

Expected behavior
Plays for a few seconds then repeats.

Actual behavior

Stream time =   0.0000, outTime =   0.0020, latency =   0.0020, frames = 344960
Stream time =   0.0000, outTime =   0.0019, latency =   0.0019, frames = 349312
Time not advancing fast enough!
An error occurred while using the portaudio stream
Error number: -9987
Error message: Wait timed out

Desktop (please complete the following information):

  • OS: [e.g. Mac OS] Linux
  • OS Version [e.g. 22] Ubuntu 18.04
  • PortAudio version: stable, nightly snapshot (which?), current on Mac 26, 2021
  • If Windows or Linux, which Host API (e.g. WASAPI): ALSA

Additional context

It seems to work fine on MacOS.

@philburk philburk added the bug Something isn't working label May 27, 2021
@xyzzy42
Copy link
Contributor

xyzzy42 commented May 27, 2021

I think Pulseaudio doesn't return stream timestamps. Was this using the pulse alsa plugin?

@philburk
Copy link
Collaborator Author

That might be the problem.

Was this using the pulse alsa plugin?

I am not explicitly trying to use pulseaudio. I am just using the default device. But I suspect pulseaudio is inserting itself in there.

Entering: pactl list
prints a lots of devices.

I am trying to disable pulseaudio on Ubuntu 18.04 and not having much luck. Any advice?

@xyzzy42
Copy link
Contributor

xyzzy42 commented May 27, 2021

Running aplay -L or arecord -L will list the alsa playback or record devices. That should tell you if pulse is one of the devices and which device is the default. The other ALSA devices are still there and Portaudio can use them. Just use the portaudio API to enumerate and select devices and pick one of the hardware devices rather than default or pulse.

Note that enumerating the pulse device may cause the hardware device(s) it will use to become busy for a short time. It is the same as a the ALSA dmix plugins this way, for which there is already code in portaudio to alter scanning order.

@philburk philburk changed the title ALSA: Pa_GetStreamTime() is not advancing ALSA: Pa_GetStreamTime() is not advancing for PulseAudio May 29, 2021
@philburk
Copy link
Collaborator Author

Thanks! aplay -l only listed one device. But bin/pa_devs list every device.
I found the if I used the "pulse" or "default" device then Pa_getStreamTime() returned zero. (BAD)
But If I used one of the explicit ALSA device then it worked fine.

So this does seem related to pulseaudio. So I updated the bug title.

Maybe we should detect pulseaudio and workaround this some way.

@xyzzy42
Copy link
Contributor

xyzzy42 commented May 30, 2021

Pretty sure this is a limitation of pulse. I haven't tested pipewire, maybe it fixes it? But I doubt it, at least not yet, pipewire doesn't seem to be working as well as pulse.

One could try to timestamp when the stream becomes read/write-able, but I'm guessing that it will be very inaccurate. Or just fabricate timestamps based on nominal rate. Which aren't really timestamps, but would allow code that expects timestamps to work as well as it's going to work when it doesn't have them.

More sophisticated would be model the actual rate with a PLL or FLL and attempt to lock that to userspace timestamps, while accounting for the large jitter in those timestamps.

@philburk philburk added P3 Priority: Normal src-alsa ALSA Host API /src/hostapi/alsa labels Feb 17, 2022
@RossBencina
Copy link
Collaborator

I wonder whether the callback timestamps are also invalid.

It would be fine to use the system monotonic clock to compute stream time and callback timestamps. We do similar things in other host APIs where there is no native stream time support.

If someone submitted a patch that provided best-effort timestamps then we would accept it.

@xyzzy42
Copy link
Contributor

xyzzy42 commented Mar 18, 2022

Yes, the callback timestamps are also all zero. Both inputBufferAdcTime and currentTime will be zero. Both stem from snd_pcm_status_get_[h]tstamp returning a zero value.

@RossBencina
Copy link
Collaborator

I wonder whether ALSA provides an API call to query whether a particular device provides timestamps?

@xyzzy42
Copy link
Contributor

xyzzy42 commented Mar 24, 2022

Good question. Basic timestamping, which is all PA uses, is supposed to be supported by all ALSA devices. Absent any hardware features, it's done in the core ALSA layers. IMHO, it's a PulseAudio flaw that it doesn't work with the virtual ALSA devices that PulseAudio creates.

There is an ALSA function, snd_pcm_status_get_audio_htstamp_report(), that could be useful. But since timestamps don't work correctly with Pulse, there's no reason to expect it to work correctly either!

I don't think it's really necessary to use it. I don't think is any way for a valid timestamp to be zero. So if we get a zero timestamp, and pulse does give us that at least, they don't work, regardless of what snd_pcm_status_get_audio_htstamp_report() might return.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working P3 Priority: Normal src-alsa ALSA Host API /src/hostapi/alsa
Projects
None yet
Development

No branches or pull requests

3 participants