0

I'm working on a simple sine wave audio generator, using libpulse on Ubuntu 20.04. It's using the pa_stream_begin_write and pa_stream_write functions within a callback function set up using:

pa_stream_set_write_callback(stream, stream_write_cb, &u);

It works, I get 30 seconds of sine wave coming out of the speakers. Each time the stream_write_cb callback function is called I use it to load up another chunk of sine wave data.

But, what happens at exactly 30 seconds?

enum pa_operation_state opState = pa_operation_get_state(o);

The opState changes to PA_OPERATION_DONE, and I don't know why. It happens at exactly 30 seconds of audio playback - so it feels like there is an internal libpulse timeout thing going on.

Anyone have any ideas how to prevent the timeout happening?

phuclv
  • 37,963
  • 15
  • 156
  • 475
Nick
  • 191
  • 2
  • 13
  • Without more code, it's very difficult to understand where the issue is. This [simple example](https://stackoverflow.com/questions/29977651/how-can-the-pulseaudio-asynchronous-library-be-used-to-play-raw-pcm-data) works without issue, and if you're just trying to make a sine-wave, you can use `pactl load-module module-sine frequency=1000`, for example – Anya Shenanigans Jan 21 '22 at 17:07
  • Yes, my project is based on that simple_example from the comment above. When I run that it emits a stream of squeeky beeps and blips from the speakers. But, it does go on forever - well past the 30 seconds that my code lasts. The difference I do see is that I'm using pa_stream_drain(s, my_drain_callback, m) to detect when the stream actually ends. In normal usage the stream shouldn't drain because I want the sine wave to be produced continuously. – Nick Jan 21 '22 at 17:56
  • Hi, back again. So, It looks like #define DEFAULT_TIMEOUT (30) which is found in src/pulse/internal.h is used as a 30 second timeout in some part of the pulse audio library. After playing 30 seconds of sinewave the timeout is triggered and playing stops. So, there is probably some mechanism to either pat the watchdog, or reset the timer, or somehow turn it off. Any ideas how I do that ? – Nick Feb 07 '22 at 18:20
  • So, I've got some more time to look at this problem. It's still a thing. I checked the stream_write_cb side of things, and the buffer is being filled with data every call. But, the problem appears to be that the callback set in pa_stream_drain gets called at exactly 30 seconds of playback. Why would that happen? And how do I stop it? – Nick May 15 '22 at 14:49
  • Further tests show that if I don't use the pa_stream_drain function then the 30 second timeout doesn't happen. So, this sounds like a "feature" of the pa_stream_drain mechanism. It looks like the stream drain logic in libpulse is waiting for the stream to finish, but won't wait forever - there is a 30 second maximum timeout. – Nick May 15 '22 at 17:28
  • OK, so I have a solution. It turns out that the stream drain callback has an int "success" flag which turns out to be 1 for when a proper stream drain has happened. And its 0 for when the stream drain mechanism got bored of waiting and gave up at the 30 second timeout. So, now I can tell if the stream has actually drained or not. Which is great. And, better - If the timeout has happened then I can simply set up another pa_stream_drain callback just like I did the first time. Now, it works. Finally. But, I wish I knew why only I am having this problem. Surely others have run in to it. – Nick May 15 '22 at 17:53

0 Answers0