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

Feature request: Flush Plugin Caches with Silence #2938

Open
GhostNaN opened this issue Feb 25, 2024 · 6 comments
Open

Feature request: Flush Plugin Caches with Silence #2938

GhostNaN opened this issue Feb 25, 2024 · 6 comments

Comments

@GhostNaN
Copy link

For a while now I have been experiencing popping/crackling when starting a new audio stream.
This issue is already well known as seen here #1856 and here #1392
So I understand that the issue is:

plugins you are using still has some of the old data saved internally when you play something new.

After doing my own testing, I can also confirm running this:
aplay -r 48000 -f S24_3LE /dev/zero as suggested by someone seems to "fix" this issue.
Although, it's less than ideal to just have a silent audio stream constantly playing in the background.

So would it be possible to implement some sort of feature to just play silence after a stream ends?
For example, having a setting in preferences that just adds 50 ms of silence or something?
The idea is just to flush the cache of the "old data" to avoid this issue.

@Digitalone1
Copy link
Contributor

Did you already enable the inactivity time option with a huge number (like 1 hour)?

@GhostNaN
Copy link
Author

GhostNaN commented Feb 25, 2024

30s, off, 3600s no change.
It's not because easyeffects is going inactive.

@wwmm
Copy link
Owner

wwmm commented Feb 25, 2024

30s, off, 3600s no change.
It's not because easyeffects is going inactive.

Run pw-dot so we can see each link state. Its output file can be viewed with the command xdot. If the links are there and still in the active state then EE is already playing silence. But there are situations where PipeWire may have paused the pipeline on its own. We create passive links so it can do that when possible.

So would it be possible to implement some sort of feature to just play silence after a stream ends?
For example, having a setting in preferences that just adds 50 ms of silence or something?
The idea is just to flush the cache of the "old data" to avoid this issue.

There isn't an elegant or straightforward way to do that. PipeWire is the one managing each filter state and there isn't a pipeline object with flushing mechanisms like in GStreamer. What we could try is some kind of hack. Creating a node like the one from the test signal that plays silence and linking it to our virtual sink. If that is going to have some unexpected side effect is hard to say without trying it.

@wwmm
Copy link
Owner

wwmm commented Feb 25, 2024

But there are situations where PipeWire may have paused the pipeline on its own.

It always does it on its own. What I meant is that it could have done that before we usually remove the links between the filters. The removal of the links is what the timeout controls.

@GhostNaN
Copy link
Author

It always does it on its own. What I meant is that it could have done that before we usually remove the links between the filters.

Like when a node suspends with ["session.suspend-timeout-seconds"] = 5 ?

The removal of the links is what the timeout controls.

I have been using qpwgraph to visualize what is going on and I could see the links being removed with the timeout.

There isn't an elegant or straightforward way to do that. PipeWire is the one managing each filter state and there isn't a pipeline object with flushing mechanisms like in GStreamer. What we could try is some kind of hack. Creating a node like the one from the test signal that plays silence and linking it to our virtual sink. If that is going to have some unexpected side effect is hard to say without trying it.

Yeah, I didn't think this was going to be clean.
And your idea of implementation was effectively what I was asking for.
If you find this to be too janky/hacky, I understand.

@wwmm
Copy link
Owner

wwmm commented Feb 25, 2024

Like when a node suspends with ["session.suspend-timeout-seconds"] = 5 ?

I am not sure. Depending on how complex the processing graph is PipeWire may or may not be able to automatically stop sending buffers to filters in pipelines whose players/recorders are inactive. We unlink the filters exactly as a workaround for the fact PipeWire is not always able to avoid wasting CPU in these situations. It is not clear to me if PipeWire is reading the timeout you are talking about when deciding if it has to stop calling filters callbacks or not.

Yeah, I didn't think this was going to be clean.
And your idea of implementation was effectively what I was asking for.
If you find this to be too janky/hacky, I understand.

Compared to what is possible to do in GStreamer it is definitely not good. But it is not the first time that the lack of flushing has caused bad side effects. Eventually we will have to force some kind of flushing. I will try to find some time to investigate how hard it will be to put a hack solution in place.

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

No branches or pull requests

3 participants