Pulseeffects: Pulseeffects CPU usage and Audio Quality

Created on 10 Sep 2019  Â·  28Comments  Â·  Source: wwmm/pulseeffects

Hi, I've been using pulseeffects on my Ubuntu 19.04 distribution installed through deb for the past few months. All working well and I am still tinkering with the settings. However, I noticed that the CPU usage with pulseeffects remains very high (average 20% every time its being used), and thereby drains battery very quickly. Anyone else experiencing this, and found a way to resolve?

Also, I had come across this git repo https://github.com/JadinAndrews/setaudio.git which talks about modifying the daemon.conf file for higher fidelity. Do you recommend using the hq.conf settings? Has anyone tried it and "seen/heard" any major enhancement to their sound?

question

Most helpful comment

@jtibrewala what are you using to measure the cpu usage? Desktop monitors like the ones from GNOME and KDE use a criteria that is different than the one used by command line programs like Top. Usually you will see higher values in Top because by default it uses Irix mode.

CPU usage will depend on the amount of plugins you have enabled and on how powerful your cpu is. On my last processors (Ryzen 1700, Ryzen 2700 and now a Ryzen 3700X) the cpu usage is almost unnoticeable like BobbyWibowo said.

It is usually worth to tweak a little the default Pulseaudio config but do not expect something magical to happen. The hq.conf in that repository sets the default sampling rate to 96 kHz. Unless you are listening to an audio content originally recorded in this sampling rate there is no advantage in doing that. You will only waste CPU power.

Changing the default default-sample-format may or may not bring benefits. I usually have mine set to s32le. This will avoid quality losses in case you listen to something that was originally recorded with a resolution above 16 bits. If that is not the case nothing will happen. Your 16 bits song won't sound better because Pulseaudio is using a larger bit depth. But at the same time they are not going to sound worse like it would happen with a downsampling. As long as you choose a high bit depth value this setting is harmless. I only suggest you take a look at the output of the command pactl list sinks and check if Pulseaudio accepted your setting. My card does not accept float32le or s24le as was set in the repository's hq.conf file.

The hq.conf file also changes default-fragments and default-fragment-size-msec. But this will only have an effect if you tell Pulseaudio to config your sound card with tsched=0(this has to be done on another file). And you may introduce cracklings if you do not set the right value for your sound card. Unfortunately this value is hardware dependent. The main advantage of trying to set the fragment manually is reducing latency. Pulseaudio configures the card to a higher than necessary latency by default. There is a decent guide about this here http://juho.tykkala.fi/Pulseaudio-and-latency.

All 28 comments

Also, I had come across this git repo https://github.com/JadinAndrews/setaudio.git which talks about modifying the daemon.conf file for higher fidelity. Do you recommend using the hq.conf settings? Has anyone tried it and "seen/heard" any major enhancement to their sound?

I only raised mine to 48kHz sample rate + float32le sample format, whose only reason I chose was because the default IRS used in JackHack96's presets was at those values. PulseEffects would "convert" the IRS if those were mismatched, I think, but I was like, "nah, I'd rather not".

Also this article came out recently on /r/linux: A complete guide of and debunking of audio on Linux, ALSA and Pulse, from which I came to the conclusion that anything higher would only be absolute wastes of processing power.

Hi, I've been using pulseeffects on my Ubuntu 19.04 distribution installed through deb for the past few months. All working well and I am still tinkering with the settings. However, I noticed that the CPU usage with pulseeffects remains very high (average 20% every time its being used), and thereby drains battery very quickly.

Alas I'm not getting this issue. I usually listen to my music with mpv with --no-video parameter, cause most of my music came from YouTube (Nightcore, indie EDMs, etc).

CPU usage

Screenshot
I saw that pulseffects mostly capped at 2%, with sometimes it went down to 1%.

Then again since I'm using those presets I mentioned, I think I only have Convolver + Equalizer enabled. Oh yeah, I'm only running Ubuntu 18.04 (KDE neon 5.16), and installed pulseeffects + the updated pulseaudio from the Ubuntu PPA.

@jtibrewala what are you using to measure the cpu usage? Desktop monitors like the ones from GNOME and KDE use a criteria that is different than the one used by command line programs like Top. Usually you will see higher values in Top because by default it uses Irix mode.

CPU usage will depend on the amount of plugins you have enabled and on how powerful your cpu is. On my last processors (Ryzen 1700, Ryzen 2700 and now a Ryzen 3700X) the cpu usage is almost unnoticeable like BobbyWibowo said.

It is usually worth to tweak a little the default Pulseaudio config but do not expect something magical to happen. The hq.conf in that repository sets the default sampling rate to 96 kHz. Unless you are listening to an audio content originally recorded in this sampling rate there is no advantage in doing that. You will only waste CPU power.

Changing the default default-sample-format may or may not bring benefits. I usually have mine set to s32le. This will avoid quality losses in case you listen to something that was originally recorded with a resolution above 16 bits. If that is not the case nothing will happen. Your 16 bits song won't sound better because Pulseaudio is using a larger bit depth. But at the same time they are not going to sound worse like it would happen with a downsampling. As long as you choose a high bit depth value this setting is harmless. I only suggest you take a look at the output of the command pactl list sinks and check if Pulseaudio accepted your setting. My card does not accept float32le or s24le as was set in the repository's hq.conf file.

The hq.conf file also changes default-fragments and default-fragment-size-msec. But this will only have an effect if you tell Pulseaudio to config your sound card with tsched=0(this has to be done on another file). And you may introduce cracklings if you do not set the right value for your sound card. Unfortunately this value is hardware dependent. The main advantage of trying to set the fragment manually is reducing latency. Pulseaudio configures the card to a higher than necessary latency by default. There is a decent guide about this here http://juho.tykkala.fi/Pulseaudio-and-latency.

@wwmm
What is the difference between s32le and float32le (single and float) in terms of quality / cpu usage?
Should I prefer one over the other?

Also I just noticed that my pulseeffeccts reports the follwing re-sampling path:
s16le -> F32LE > s16le

Isn't that a bit of madness? It could have just staid at s16le and not re-sample at all in the first place?

You are not going to notice quality differences between s32le and float32le. And I also doubt a difference in cpu usage would be noticeable.

Almost all plugins available in PE require F32LE(the same as float32le) as sample format. There is no choice. The conversion has to be made. But this is not what we usually call resampling(changing from a rate to another). In this case only the sample format is being changed. The last 16 bits not present in the original content(s16le) will be filled with harmless zeros. The original content will be preserved. What you do not want are unnecessaries changes in rate. Like going from 48 kHz to 44.1 kHz or the other way around.

Interesting. Well then I might just as well set "default-sample-format = F32LE" in pulseaudio.
For default-rample-rate I wonder wether I should go with 48000 as default or 44100. But I believe 44100 is more common?

Edit: Funny.. when setting "default-sample-format = float32le" then pulseeffectt will show:
float32le -> F32LE -> s32le

And setting "F32LE" in pulseaudio won't work :P

This also happens in my sound card. It does not accept float32le so Pulseaudio fallbacks to the closest one s32le.

float32le and F32LE are the same format. Pulseaudio devs prefer the first name and the last one is the name used by GStreamer and the plugins. In both cases you have a float number using 32 bits and with bytes ordered accordingly to the little-endian standard.

I suggest you open the file /etc/pulse/daemon.conf and change avoid-resampling value to true. In case you do not want to edit a system file just copy the file daemon.conf to ~/.config/pulse. Pulseaudio will use config files in the user home if there is one there. The advantage of doing all this is that Pulseaudio will automatically change our sink sampling rate to the value used by your audio player. You need Pulseaudio 13(or a patched 12 version) for this to work with PulseEffects.

@wwmm thanks for that explenation! I also found this tutorial and wonder if it is useful? If so, maybe pulseeffects could calculate & apply the correct values automatically for each individual setup?

https://forums.linuxmint.com/viewtopic.php?f=42&t=44862

It gives you a decent starting value for the parameters. But as I have told above remember to set tsched=0. Otherwise Pulseaudio will ignore your custom values.

Unfortunately this cannot be automated because Pulseaudio does not offer a way to set these kind of values on the fly. You have to edit its configuration files.

Yep, thanks for the reminder with "tsched" :)

Hmm I meant that pulseeffects could offer a button to calculate those values based on the specific system it is installed on and another button to apply those values into the users config files.
Just to make it easier for everyone to have a better optimized PA.
Also, just like pulseeffects can apply specific settings for specific headphones conntected, we could change the PA settings for the specific hardware connected :D

After the initial elation of hearing actual bass in these overpriced Klipsch Reference x6i earbuds, I too noticed that PulseEffects consumes about 20% CPU while in use.

Not a huge deal since even if the laptop fans turn on due to the added CPU usage, I'll probably have the earbuds in listening to music, so wouldn't notice anyway.

Still, in the interest of consuming fewer resources, what's the consensus here, just the cost of doing business, or is there a way to bring PulseEffects CPU overhead down into the single digits?

EDIT:
Fedora 31 on a Dell Precision 5540

EDIT2:
Using Limiter (Input Gain: -15 dB) and Bass Enhancer (Amount: +10) effects, with CMUS player. While top may not be entirely accurate, it does show pulseeffects process consuming 23% CPU, and more importantly, CPU temps go from 40C to 47C. If I turn off Show Spectrum in settings then CPU usage goes down to 15% for the pulseeffects process (spectrum graph probably kicking in the iGPU on the i5-9400H in this machine).

@godenji how many logical cores does your cpu have? I ask because top standard scale goes from 0% to number_of_cores * 100 %. Right now I am on a Ryzen 3700x and with a few plugins enabled PulseEffects has a cpu usage of around 8% in a scale that goes to 16 * 100% = 1600%. PE is running as a service(window closed). In order words I do not even notice how much cpu it is using...

This will change with cpu of course. In a laptop I would expect things to be worse. In any case there isn't much I can do about it. The cpu intensive code is in the third party plugins and maybe also in GStreamer. Of all the plugins visible to the user the only ones I wrote are the autogain, crystalizer and the convolver.

You may try to increase the block size parameter in our settings menu. In some plugins this helps. In others it makes no difference.

4 cores, 8 virtual. The CPU usage isn't necessarily a big deal, it's the
rise in temperature (more heat, more potential for the fans to kick in).

I'll try the block size setting, thanks.

p.s. the application works great, grateful to have some bass in these
anemic earbuds.

On Sun, Nov 17, 2019, 11:30 AM Wellington Wallace notifications@github.com
wrote:

@godenji https://github.com/godenji how many logical cores does your
cpu have? I ask because top standard scale goes from 0% to number_of_cores

  • 100 %. Right now I am on a Ryzen 3700x and with a few plugins enabled
    PulseEffects has a cpu usage of around 8% in a scale that goes to 16 *
    100% = 1600%. PE is running as a service(window closed). In order words I
    do not even notice how much cpu it is using...

This will change with cpu of course. In a laptop I would expect things to
be worse. In any case there isn't much I can do about it. THe cpu intensive
code is in the third party plugins and maybe in GStreamer. Of the all the
plugins visible to the user the only ones I wrote are the autogain,
crystalizer and the convolver.

You may try to increase the block size parameter in our settings menu. In
some plugins this helps. In others it makes no difference.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/wwmm/pulseeffects/issues/568?email_source=notifications&email_token=AAB2HXOSX5FP6267YGJMYHDQUFWRPA5CNFSM4IVCVWE2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEEIQDOI#issuecomment-554762681,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAB2HXOYGYT37WC6XL3FF4DQUFWRPANCNFSM4IVCVWEQ
.

I would like to note that nobody should be using tsched=0 in 2019 with modern, well-supported hardware. There are other ways to improve native pulseaudio latency that don't involve changing "deprecated" settings (specifically, fragments and fragment_size), such as adjusting the tsched_buffer_* options[1].
Using a realtime-enabled kernel such as one with the CK patchset (with the MuQSS scheduler + schedutil governor) combined with carefully adjusted rtprio and nice levels for the pulseaudio daemon is also strongly recommended.

Disabling timer-based scheduling is only a "hack" intended to work around buggy cards or drivers.

Did you measure the latency difference in your approach? I have my doubts that a patched kernel is enough. The problem is that in some situations the default latency set by Pulseaudio on the card sink is too high. And it is hard to believe that it will magically change its behavior just because it saw a patched kernel there.

I use the optical port of my card and by default Pulseaudio sets a latency of 100 ms on it when it is totally fine to use 5 ms. The large value may make sense when using the analog outputs. But for the digital output it is totally unnecessary. The only way I found to change that was setting the fragment size or the tsched buffer size manually.

Yes, I actually saw the latency go from ~30ms or higher to <8ms (!) (consistently) after changing kernels. Note: I don't use PulseEffects these days, but the native *module-equalizer-sink* instead as it's good enough for me.
These values are for sinks. For sources (mic input) the difference is a bit less dramatic, but becomes more relevant when combining SoX with a module-null-sink for a processed loopback sink (such as in this case). _Btw: I'm talking about a low-cost solution over an USB 2.0 digital interface (CM108 chipset with the IEC 958 codec)._
Note 2: Too bad the native equalizer sink adds an excessively high latency of >100ms on top of my audio output. It's got its fair share of problems, including not handling rewinds as well as it could (being a native module).

Btw I have these on my daemon.conf (and have had so since before using the realtime kernel, at which point I used to get more crackling and latency in spite of the settings):

high-priority = yes
nice-level = -14
realtime-scheduling = yes
realtime-priority = 10
rlimit-nice = 39
rlimit-rtprio = 98

Of course, proper limit allowances must be set (in /etc/systemd/system.conf.d/limits.conf for Arch Linux), otherwise these settings will not be effective (rt-kit will fail to set the proper realtime priority). I tried higher priorities but really a nice value of -14 and rt-prio 10 (reported by htop as -11) are enough.

P.S. I found out just today that you ported PulseEffects to C++ (which is why I'm going through a lot of old issues here, out of idling curiosity xD) - congratulations!

TLDR: the patched kernel is not enough by itself but it helps wonders combined with the proper settings.

The only way I found to change that was setting the fragment size or the tsched buffer size manually.

Yeah - the buffer size is kinda tricky to set up but if you can get by with that alone it's much better than reverting to the ancient interrupt-based scheduling model.

The port to C++ was made many months ago :-)

I figured ^^ v4.0, right?

Btw, if you feel like trying a realtime-patched kernel without having to build yourself, check these:

Yes. It was on version 4 after an insane amount of work. Well... It is the price you pay when you do not set big goals from the beginning XD

Right now I am using a custom kernel I built with the fsync patch. Maybe one day I will try these other patches. But as I am not doing any kind of audio recording or music production I still had no need for a realtime kernel. Even with CONFIG_HZ set to 100 Hz and the tsched=0 in Pulseaudio. Maybe it is because I am using the digital output...

EDIT:

Or maybe it is because my CPU(ryzen 3700x) has 16 logical cores. As far as I remember the interrupts are done independently for each logical core

I enabled tsched again and for some reason Pulseaudio is using the custom fragment size of 1 ms I have set in daemon.conf. I am surprised. Many places in the web say that Pulseaudio ignores this value when tsched is enabled. It is good to know that this is not the case.

Well... Pulseaudio doc also says that the fragment value should be ignored https://github.com/pulseaudio/pulseaudio/blob/f62a49b8cf109c011a9818d2358beb6834e6ec25/man/pulse-daemon.conf.5.xml.in#L525. But it isn't. Without the 1 ms fragment the sink latency goes to 100 ms and this is reflected in PE title bar after asking GStreamer the total latency. After setting the fragment the sink latency is reduced to approximately 5 ms and the total latency shown in PE decreases accordingly. Weird.

The only explanation I can think of is that my sound card driver does not support timer based scheduling :O. This is surprising considering that the card is an ALC1220 in a X470 ryzen motherboard...

I started pulseaudio manually so I could see its debug messages while the card was being configured. It is disabling timer based scheduling for my card :o

alsa-util.c: Disabling tsched mode since BATCH flag is set
alsa-sink.c: Cannot enable timer-based scheduling, falling back to sound IRQ scheduling.

I wonder what is this BATCH flag that is being set... And why this is happening...

I looked at Pulseaudio sources and the batch flag comes from ALSA after a call to snd_pcm_hw_params_is_batch. According to ALSA docs what this function does is Check if hardware does double buffering for data transfers for given configuration. It seems my card does not support that =/

As far as I remember the interrupts are done independently for each logical core

Indeed they are.

Regarding the fragment size value, according to the sources, it definitely should be ignored if using timer-based scheduling (function pa_alsa_set_hw_params(...), where the period_size parameter is the fragment_size divided by frame_size):

if (_use_tsched && tsched_size > 0) {
    _buffer_size = (snd_pcm_uframes_t) (((uint64_t) tsched_size * _ss.rate) / ss->rate);
    _period_size = _buffer_size;
} else {
    _period_size = (snd_pcm_uframes_t) (((uint64_t) _period_size * _ss.rate) / ss->rate);
    _buffer_size = (snd_pcm_uframes_t) (((uint64_t) _buffer_size * _ss.rate) / ss->rate);
}

However, there is some "magic" going on in that function. Maybe you're having tsched disabled by some of that (perhaps this line combined with this one)?

I looked at Pulseaudio sources and the batch flag comes from ALSA after a call to snd_pcm_hw_params_is_batch. According to ALSA docs what this function does is Check if hardware does double buffering for data transfers for given configuration. It seems my card does not support that =/

Hah, mistery solved. I just came across that myself.

It would be nice to get tsched support information without having to look at Pulseaudio's logs... As I have a new sound card I assumed that its driver would be using what is considered "modern technology" =/. Fortunately I do not have any problems. But it is still disappointing...

And to make things even more weird it seems that usb devices support the feature =/ https://gitlab.freedesktop.org/arun/pulseaudio/commit/810aa36189f82f77403826defa76a4f9f1f01454

This explains why tsched has to be disabled when the device uses batch mode https://mailman.alsa-project.org/pipermail/alsa-devel/2013-December/069919.html

And this is why the batch flag was turned on in the kernel side https://github.com/torvalds/linux/commit/c02f77d32d2c45cfb1b2bb99eabd8a78f5ecc7db. The Realtek codec in the latest AMD boards is not behaving as it should =/

Sorry for not responding earlier. Damn, that's sad :/ I hate seeing those kinds of hacks being implemented, especially in the kernel.

Thanks for pointing me to these!

Was this page helpful?
0 / 5 - 0 ratings