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

[pulseaudio] For source, default timeout should be disconnection ASAP #15314

Merged
merged 2 commits into from
Aug 3, 2023

Conversation

dalgwen
Copy link
Contributor

@dalgwen dalgwen commented Jul 27, 2023

Hello all.
When reading from a pulseaudio audio source, a weird behaviour could happen.

Explanation:
There is a (configurable) grace timeout between disconnection. Each read from the socket pushes the timeout forward in time.
This is good for the sink part, as it reduces the need to reconnect socket (and so improve latency), but not so for the source part.

When we get for the first time an inputstream and pass it to the STT service, the binding connects to the socket and returns an appropriate inputstream whose data, hopefully, will immediately be consumed by a TTS service.
When all needed data is collected, the TTS closes the stream from its side (TTS choice, based on VAD or its own max timeout).
The socket is NOT closed. Because there is a pipe in between (usefull to send data to multiple input stream). It is the dedicated pipe that is closed.
The socket remains open during a grace period, allowing a new inputstream to consume data from it faster.
But as the socket remains open, with no inputstream consuming it, audio data is accumulating on the pulseaudio server side.
Then, if openHAB opens a new input stream (because a new vocal command is to be issued) on the socket during the grace period, the pulse audio server will send all accumulated data inbetween to it.

This bug can only happen if openHAB doesn't handle the wake word (because if so, the binding never stops to consume data).
It is the case with the new method "listenAndAnswer".

Solution:
If the socket is disconnected immediately after use, no such behavior happens.
However, I would like to keep the graceperiod as a configuration parameter, for genericity with the sink part. And these weird behaviour could be usefull for whatever use case we cannot imagine right now.
So I suggest to make a new "0" timeout parameter that logically process to disconnect as soon as possible. And make it the default value for source, and let the parameter be an "advanced" parameter to suggest users to not meddle with it without really knowing what they do.

As the method "listenAndAnswer" is new, it could be seen as a regression introduced in 4.0.0 ? On the other side, I don't think many users will use/see this.
Actually, what is the policy for backporting bug fix in release patch branch ?

@dalgwen dalgwen added the bug An unexpected problem or unintended behavior of an add-on label Jul 27, 2023
@dalgwen dalgwen requested a review from GiviMAD July 27, 2023 22:30
To avoid weird behaviour, such as pulseaudio server storing audio data between inputstream get/read and then sending the backlog all at once when finally reading, we must disconnect immediately thereafter.

Signed-off-by: Gwendal Roulleau <gwendal.roulleau@gmail.com>
@dalgwen dalgwen force-pushed the pulseaudio_source_disconnection_asap branch from d00c182 to 4b1c6cc Compare July 27, 2023 22:33
@dalgwen dalgwen marked this pull request as ready for review July 28, 2023 09:53
@dalgwen dalgwen requested a review from peuter as a code owner July 28, 2023 09:53
Copy link
Member

@GiviMAD GiviMAD left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a minor comment, otherwise LGTM.
Thank you for detecting the issue.

@@ -75,7 +75,7 @@ thing-type.config.pulseaudio.source.simpleProtocolSourceFormat.option.s24be = PC
thing-type.config.pulseaudio.source.simpleProtocolSourceFormat.option.s32le = PCM signed 32-bit little-endian
thing-type.config.pulseaudio.source.simpleProtocolSourceFormat.option.s32be = PCM signed 32-bit big-endian
thing-type.config.pulseaudio.source.simpleProtocolSourceIdleTimeout.label = Idle Timeout
thing-type.config.pulseaudio.source.simpleProtocolSourceIdleTimeout.description = Timeout in ms after which the connection will be closed when no stream is running. This ensures that your speaker is not on all the time and the pulseaudio source can go to idle mode. -1 for no disconnection.
thing-type.config.pulseaudio.source.simpleProtocolSourceIdleTimeout.description = Timeout in ms after which the connection will be closed when no stream is running. This ensures that your mic is not on all the time and the pulseaudio source can go to idle mode. -1 for no disconnection. 0 for immediate disconnection (recommended value, or expect strange behaviour !).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can put something more clarifying like "recommended value to avoid audio delay".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Waiting for the feedback to this comment before merging.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it could be more clarifying. But it is not really an audio delay : it takes audio data from "before" the wanted data.
Maybe : "or expect irrevelant audio data capture"
(not satisfied by this either, I'm open to suggestion)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe "to avoid problems with buffered audio data" or "to avoid capturing buffered audio"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, feels better.
"to avoid capturing unwanted buffered audio"
Done

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

Copy link
Contributor

@lolodomo lolodomo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Apply revision

Signed-off-by: Gwendal Roulleau <gwendal.roulleau@gmail.com>
@dalgwen
Copy link
Contributor Author

dalgwen commented Aug 3, 2023

Thank you @lolodomo

@lolodomo lolodomo merged commit f98ed3f into openhab:main Aug 3, 2023
@lolodomo lolodomo added this to the 4.1 milestone Aug 3, 2023
@dalgwen dalgwen deleted the pulseaudio_source_disconnection_asap branch August 13, 2023 18:23
Pshatsillo pushed a commit to Pshatsillo/openhab-addons that referenced this pull request Sep 29, 2023
…openhab#15314)

* [pulseaudio] For source,  default timeout should be disconnection ASAP

To avoid weird behaviour, such as pulseaudio server storing audio data between inputstream get/read and then sending the backlog all at once when finally reading, we must disconnect immediately thereafter.

---------

Signed-off-by: Gwendal Roulleau <gwendal.roulleau@gmail.com>
Co-authored-by: Gwendal Roulleau <gwendal.roulleau@gmail.com>
austvik pushed a commit to austvik/openhab-addons that referenced this pull request Mar 27, 2024
…openhab#15314)

* [pulseaudio] For source,  default timeout should be disconnection ASAP

To avoid weird behaviour, such as pulseaudio server storing audio data between inputstream get/read and then sending the backlog all at once when finally reading, we must disconnect immediately thereafter.

---------

Signed-off-by: Gwendal Roulleau <gwendal.roulleau@gmail.com>
Co-authored-by: Gwendal Roulleau <gwendal.roulleau@gmail.com>
Signed-off-by: Jørgen Austvik <jaustvik@acm.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug An unexpected problem or unintended behavior of an add-on
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants