easyeffects icon indicating copy to clipboard operation
easyeffects copied to clipboard

Feature Request: Manual reset of plugin processing delay (especially for Deep Noise Remover(DeepFilterNet))

Open hayama77 opened this issue 6 months ago • 7 comments

EasyEffects Version

7.2.3

What package are you using?

Other (specify below)

Distribution

OS: Raspberry Pi OS Bookworm (Debian 12-based) with PREEMPT-RT kernel, Easyeffects: compiled from source

Describe the bug

Hi, I'm currently using Easyeffects on a Raspberry Pi 5 with a PREEMPT-RT kernel and PipeWire configured in real-time mode (libpipewire-module-rt). My goal is to minimize audio latency during live processing, and for the most part, it works well.

However, when I enable the DeepFilterNet plugin, I observe that audio latency begins to accumulate over time — especially after launching other applications or under moderate CPU load. Underrun warnings start to appear, and the perceived audio delay increases significantly.

Critically, even after CPU usage returns to normal, this accumulated delay does not return to the original baseline latency.

For example: Base latency with DeepFilterNet OFF: ~15ms Latency with DeepFilterNet ON: ~55ms (expected, due to its processing load) Latency after DeepFilterNet ON + moderate load: 100ms+ (accumulated buffer delay) Turning OFF DeepFilterNet → latency resets to 15ms Turning ON again → latency jumps back to 100ms+ (not 55ms)

This suggests that some internal buffers or scheduling structures are not being reset when the plugin is toggled back ON.

■Request: Could you please consider implementing a feature to manually reset the plugin’s processing state or internal delay buffers, perhaps via the GUI or a D-Bus command? This would be especially useful for high-CPU-load plugins like DeepFilterNet, which are sensitive to underruns in low-latency environments.

■Supporting Logs: Below is a sample log output showing repeated underruns:

2025-06-15T02:14:15.407Z | WARN | deep_filter_ladspa | DF 13206e5c45af | Underrun detected (RTF: 1.14). Processing too slow! 2025-06-15T02:14:17.292Z | WARN | deep_filter_ladspa | DF 13206e5c45af | Underrun detected (RTF: 1.92). Processing too slow! 2025-06-15T02:14:20.120Z | WARN | deep_filter_ladspa | DF 13206e5c45af | Underrun detected (RTF: 3.05). Processing too slow! 2025-06-15T02:14:20.235Z | WARN | deep_filter_ladspa | DF 13206e5c45af | Underrun detected (RTF: 5.75). Processing too slow!

The plugin’s performance is excellent when resources are available. But under transient CPU load, there is no way to recover the original processing latency without fully restarting Easyeffects — which is not ideal for live environments.

■Environment: Easyeffects version: 7.2.3 DeepFilterNet: LADSPA version PipeWire version: 1.5.0 OS: Raspberry Pi OS Bookworm (PREEMPT-RT kernel) Sample rate: 96 kHz (also 48kHz) Quantum: 960 CPU load: ~40% when DeepFilterNet is active

■Proposed Solutions:

  • Add a GUI or CLI option to "flush/reinitialize" a plugin instance
  • Provide a D-Bus command to reload LADSPA plugin state -Automatically reset processing delay when plugin is toggled OFF → ON

Thank you very much for this great software. I’d be happy to help test any implementation. Best regards,

Expected Behavior

Refer to above.

Debug Log

2025-06-15T02:14:15.407Z | WARN | deep_filter_ladspa | DF 13206e5c45af | Underrun detected (RTF: 1.14). Processing too slow! 2025-06-15T02:14:17.292Z | WARN | deep_filter_ladspa | DF 13206e5c45af | Underrun detected (RTF: 1.92). Processing too slow! 2025-06-15T02:14:20.120Z | WARN | deep_filter_ladspa | DF 13206e5c45af | Underrun detected (RTF: 3.05). Processing too slow! 2025-06-15T02:14:20.235Z | WARN | deep_filter_ladspa | DF 13206e5c45af | Underrun detected (RTF: 5.75). Processing too slow!

Additional Information

No response

hayama77 avatar Jun 15 '25 02:06 hayama77

Could you please consider implementing a feature to manually reset the plugin’s processing state or internal delay buffers, perhaps via the GUI or a D-Bus command?

Hum... As I am not this plugin's author the only way is an ugly way. Destroying the whole plugin instance and recreating it. It is doable. But jumps in audio level as well as noises can happen when doing things this way.

PipeWire configured in real-time mode (libpipewire-module-rt).

Can you check if that is actually working? Right now a bug in xdg-desktop-portal is not allowing realtime priorities to be set by PipeWire https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4748. Before adding a toggle for this it would be good to know if just having realtime properly working isn't enough.

wwmm avatar Jun 15 '25 14:06 wwmm

Hum... As I am not this plugin's author the only way is an ugly way. Destroying the whole plugin instance and recreating it. It >is doable. But jumps in audio level as well as noises can happen when doing things this way.

Thank you.

  1. I completely agree with your assessment. It is indeed a "workaround" at the host level, not an elegant fix within the plugin itself. Your concern about audio artifacts like clicks, pops, or level jumps during re-initialization is also very valid and a crucial point.

  2. From a user's perspective, the current situation results in uncontrollable, persistent latency that makes the system unusable until a full application restart.

In comparison, a brief, controlled, and predictable audio artifact that occurs only when the user intentionally presses a "Reset" button is a far more acceptable trade-off. It empowers the user to reclaim a low-latency state on demand.

  1. Thank you again for considering this. Even if it's a pragmatic workaround, a feature like this would be a game-changer for users on CPU-constrained systems like the Raspberry Pi.

Can you check if that is actually working? Right now a bug in xdg-desktop-portal is not allowing realtime priorities to be set >by PipeWire https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4748. Before adding a toggle for this it would be >good to know if just having realtime properly working isn't enough.

Thank you for the info. However, I checked whether the PipeWire process was running with RT scheduling using the following command:

mac@raspberrypi:~ $ ps -Leo pid,rtprio,cmd | grep pipewire 5297 - /usr/bin/pipewire -c /etc/pipewire/pipewire.conf -v 5297 88 /usr/bin/pipewire -c /etc/pipewire/pipewire.conf -v 5297 20 /usr/bin/pipewire -c /etc/pipewire/pipewire.conf -v 5302 - /usr/bin/pipewire-pulse 5302 - /usr/bin/pipewire-pulse 5302 20 /usr/bin/pipewire-pulse 5339 - grep --color=auto pipewire

⇨There are processes whose rtprio is a number (e.g. 20 or 88) instead of "-", so I've determined that they are running with RT priority.  (^_^) For your reference, as I already reported, I am using pipewire 1.5.0.

hayama77 avatar Jun 16 '25 02:06 hayama77

Hi, I have considered the mechanism of the occurrence of the latency problem I reported. I will record it as a memo for myself. I hope it will be helpful.

** Technical Analysis of Persistent Latency in EasyEffects/PipeWire **

  1. The Mechanism of Persistent Latency The issue of escalating audio latency that persists even after toggling a heavy plugin (like DeepFilterNet) OFF and ON is rooted in PipeWire's dynamic latency management and stability-focused design. The mechanism can be broken down into four stages:

(1) Trigger: Processing Underrun When system CPU load increases, a processing-intensive plugin like DeepFilterNet may fail to complete its audio processing within the allocated time slice. This results in a buffer underrun.

(2) PipeWire's Response: Dynamic Buffer Expansion To prevent audible clicks or dropouts (xruns), PipeWire's default behavior is to respond to an underrun by dynamically increasing the size of the processing buffer for the problematic node. This gives the plugin more time to complete its work, stabilizing the audio stream at the cost of increased latency.

(3) State Persistence: The "Sticky" Buffer Crucially, PipeWire is designed to prioritize stability. Once a larger, stable buffer size has been established for a node, PipeWire will not automatically reduce it, even if the CPU load subsequently decreases. The system assumes this larger buffer is the new "safe" operating parameter, causing the high latency to become persistent for that node.

(4) Latency Replication: Bypass and Re-engagement Toggling the plugin OFF within EasyEffects simply bypasses the audio stream around the corresponding node in the PipeWire graph. The node itself, along with its enlarged buffer state, is preserved. When the plugin is toggled back ON, the audio stream is rerouted through this same node, which instantly reintroduces the previously established high latency.

hayama77 avatar Jun 16 '25 04:06 hayama77

Thank you for the info. However, I checked whether the PipeWire process was running with RT scheduling using the following command:

PipeWire's process probably has the correct priorities. What I had in mind was the EasyEffects thread that process audio buffers. Or in other words the plugins thread. The xdg-desktop-portal bug is preventing this one from getting realtime priorites.

Run chrt -ap pid where pid is EasyEffects pid. When things are working a thread with SCHED_FIFO|SCHED_RESET_ON_FORK will be there.

wwmm avatar Jun 16 '25 05:06 wwmm

Thank you for your feedback. Based on your advice, I have investigated whether the EasyEffects plugin threads are running with real-time (RT) scheduling. Below is a summary of my findings.

1.Test Environment Platform: Raspberry Pi 5 OS: Debian-based with PREEMPT_RT kernel PipeWire version: 1.5.0 EasyEffects installation: Native build (not Flatpak) Plugins in use: Deep Noise Remover (DeepFilterNet)

2.Command Executed ps -e | grep easyeffects => 841434 pts/1 00:00:05 easyeffects

chrt -ap 841434

3.Observed Output (Excerpt) pid 841434's current scheduling policy: SCHED_OTHER ... pid 841457's current scheduling policy: SCHED_FIFO|SCHED_RESET_ON_FORK pid 841457's current scheduling priority: 83 ...

4.Conclusion (1) At least one EasyEffects thread (PID 841457) is confirmed to be running with real-time scheduling (SCHED_FIFO|SCHED_RESET_ON_FORK) and a priority of 83.

(2) This indicates that RT priority is being applied, and the issue with xdg-desktop-portal does not completely block RT thread creation in my case.

(3) However, only one RT thread was observed. Most other threads are still running under SCHED_OTHER, which may suggest that not all plugin processing threads receive RT scheduling.

5.Remaining Issue Despite the presence of an RT thread, I still experience severe audio latency (>100ms) when using heavy plugins like DeepFilterNet. This latency persists even after toggling the plugin off and on.

hayama77 avatar Jun 18 '25 00:06 hayama77

However, only one RT thread was observed. Most other threads are still running under SCHED_OTHER, which may suggest that not all plugin processing threads receive RT scheduling.

This is the normal behavior. There is only one plugin thread.

Despite the presence of an RT thread, I still experience severe audio latency (>100ms) when using heavy plugins like DeepFilterNet. This latency persists even after toggling the plugin off and on.

Hum... Then the ugly hack where the plugin instance is destroyed may be needed. But probably only for the deepfilter plugin. Doing this for all plugins would just waste effort as most of them do not buffer so much data.

wwmm avatar Jun 18 '25 02:06 wwmm

Hum... Then the ugly hack where the plugin instance is destroyed may be needed. But probably only for the deepfilter >plugin. Doing this for all plugins would just waste effort as most of them do not buffer so much data.

Thank you. I completely agree with you. I have tried many plugins, but the only plugin that causes Underrun is DeepFilterNet (DFN). Therefore, if you could provide a mechanism (GUI) to reset the delay time only for DFN, that would be enough. Please consider this.

hayama77 avatar Jun 18 '25 02:06 hayama77

The Deep Noise Remover plugin in our current master branch has a "reset history" button. We can close this issue.

wwmm avatar Sep 27 '25 22:09 wwmm

Thank you very much. I appreciate your efforts!!

hayama77 avatar Sep 27 '25 22:09 hayama77