[GUIDE] Framework DSP — better Linux audio

There is another thing I now do. When a new sink appears (e.g. plugging in HDMI) the effects are still applied making it sound wrong on my big sound system. So I removed -l HifiScan+EEGuide from the start command so I am now only starting easyeffects --gapplication-service in the background. Easy Effects seems to restore the last loaded configuration anyway.
The pipewire tab in Easy Effects has automatically loaded presets so I made an additional empty preset without any effects in it and added two autoload entries. One for the Family 17h/19h HD Audio Controller Analog Stereo sink, that loads the framework specific preset while the other one for Rembrandt Radeon High Definition Audio Controller Digital Surround 7.1 (HDMI) loads the empty profile.
This now switches nicely between the profiles when plugging into my AV receiver with HDMI.

1 Like

These IRs sound pretty good, except for a very annoying +7dB peak around 1850hz. Is this something you have experienced at all?

Hmm, it is on the response curve, but I don’t notice it making anything worse — I’ve noticed no distortion or perceivable volume change artifacts around those frequencies… how exactly is it annoying to you?

upd: I’ve also just did manual testing (set a tone generator to 1850Hz with EE off), and it does appear to sound really quiet for max volume

Do you by chance work with metals or place your laptop near metal shavings? 'Cause I’ve had weird distortions caused by metal shavings stuck in speakers, and it resolved after I carefully went around the perimeter of both speakers with a magnet wrapped in a soft tissue, and collected them all.

The speakers don’t appear to have any visible accumulation of metal shavings but by chance I have some nice magnets arriving in a few days, so I can double check. Here’s a (bad) recording of what your HiFiScan preset sounds like for me: https://gc.gy/1852.flac. With an added filter around that frequency it sounds passable (everything is an improvement over the stock speaker sound :smile:)

This is the best profile I’ve used yet. I have a few comments on how I tweaked the config to my liking.

I noticed that the Filter effect was cutting away audible bass frequencies. I decreased the cutoff frequency as well as increased the slope. This made the bass come through much better.

I’ve (personally) found that the Bass Enhancer is not needed, as the bass comes through well enough already. In my config below, I’ve left the effect in, but disabled, as there’s no serious issues with it, just that I didn’t like the sound of it.

In terms of IRs, the 27dB IR is indeed best. The problem that it “cuts volume too much” is not a problem, we simply have to increase the gain. Note that the gain has to come before the compressor, not the limiter, or you will hear very audible clipping artifacts. In my config, I simply added the gain at the output of the Convolver.

The gain unfortunately gives very audible artifacts in the bass frequencies, so I set the Makeup for Band 1 of the Multiband Compressor to 0 dB, which resolved the distortion.

In total, the sound is much bigger, with the bass louder, and the trebles sound clearer to me as well.

This is my current config (replace %CFG% with the path to your config file):

{
    "output": {
        "bass_enhancer#0": {
            "amount": 4.0,
            "blend": 0.0,
            "bypass": true,
            "floor": 10.0,
            "floor-active": true,
            "harmonics": 10.0,
            "input-gain": 0.0,
            "output-gain": 0.0,
            "scope": 200.0
        },
        "blocklist": [],
        "convolver#0": {
            "autogain": true,
            "bypass": false,
            "input-gain": 0.0,
            "ir-width": 100,
            "kernel-path": "%CFG%/irs/IR_22ms_27dB_5t_15s_0c.irs",
            "output-gain": 6.0
        },
        "filter#0": {
            "balance": 0.0,
            "bypass": false,
            "equal-mode": "IIR",
            "frequency": 60.0,
            "gain": 0.0,
            "input-gain": 0.0,
            "mode": "RLC (BT)",
            "output-gain": 0.0,
            "quality": 16.0,
            "slope": "x16",
            "type": "High-pass",
            "width": 1.0
        },
        "limiter#0": {
            "alr": false,
            "alr-attack": 5.0,
            "alr-knee": 0.0,
            "alr-release": 50.0,
            "attack": 2.0,
            "bypass": false,
            "dithering": "None",
            "external-sidechain": false,
            "gain-boost": true,
            "input-gain": 0.0,
            "lookahead": 4.0,
            "mode": "Herm Thin",
            "output-gain": 0.0,
            "oversampling": "Half x4(2L)",
            "release": 8.0,
            "sidechain-preamp": 0.0,
            "stereo-link": 100.0,
            "threshold": 0.0
        },
        "multiband_compressor#0": {
            "band0": {
                "attack-threshold": -16.0,
                "attack-time": 150.0,
                "boost-amount": 6.0,
                "boost-threshold": -72.0,
                "compression-mode": "Downward",
                "compressor-enable": true,
                "external-sidechain": false,
                "knee": -12.0,
                "makeup": 0.0,
                "mute": false,
                "ratio": 5.0,
                "release-threshold": -100.0,
                "release-time": 300.0,
                "sidechain-custom-highcut-filter": false,
                "sidechain-custom-lowcut-filter": false,
                "sidechain-highcut-frequency": 500.0,
                "sidechain-lookahead": 0.0,
                "sidechain-lowcut-frequency": 10.0,
                "sidechain-mode": "RMS",
                "sidechain-preamp": 0.0,
                "sidechain-reactivity": 10.0,
                "sidechain-source": "Middle",
                "solo": false,
                "stereo-split-source": "Left/Right"
            },
            "band1": {
                "attack-threshold": -24.0,
                "attack-time": 150.0,
                "boost-amount": 6.0,
                "boost-threshold": -72.0,
                "compression-mode": "Downward",
                "compressor-enable": true,
                "enable-band": true,
                "external-sidechain": false,
                "knee": -9.0,
                "makeup": 5.0,
                "mute": false,
                "ratio": 3.0,
                "release-threshold": -100.0,
                "release-time": 200.0,
                "sidechain-custom-highcut-filter": false,
                "sidechain-custom-lowcut-filter": false,
                "sidechain-highcut-frequency": 1000.0,
                "sidechain-lookahead": 0.0,
                "sidechain-lowcut-frequency": 500.0,
                "sidechain-mode": "RMS",
                "sidechain-preamp": 0.0,
                "sidechain-reactivity": 10.0,
                "sidechain-source": "Middle",
                "solo": false,
                "split-frequency": 250.0,
                "stereo-split-source": "Left/Right"
            },
            "band2": {
                "attack-threshold": -24.0,
                "attack-time": 100.0,
                "boost-amount": 6.0,
                "boost-threshold": -72.0,
                "compression-mode": "Downward",
                "compressor-enable": true,
                "enable-band": true,
                "external-sidechain": false,
                "knee": -9.0,
                "makeup": 5.0,
                "mute": false,
                "ratio": 3.0,
                "release-threshold": -100.0,
                "release-time": 150.0,
                "sidechain-custom-highcut-filter": false,
                "sidechain-custom-lowcut-filter": false,
                "sidechain-highcut-frequency": 2000.0,
                "sidechain-lookahead": 0.0,
                "sidechain-lowcut-frequency": 1000.0,
                "sidechain-mode": "RMS",
                "sidechain-preamp": 0.0,
                "sidechain-reactivity": 10.0,
                "sidechain-source": "Middle",
                "solo": false,
                "split-frequency": 1250.0,
                "stereo-split-source": "Left/Right"
            },
            "band3": {
                "attack-threshold": -24.0,
                "attack-time": 80.0,
                "boost-amount": 6.0,
                "boost-threshold": -72.0,
                "compression-mode": "Downward",
                "compressor-enable": true,
                "enable-band": true,
                "external-sidechain": false,
                "knee": -9.0,
                "makeup": 5.0,
                "mute": false,
                "ratio": 4.0,
                "release-threshold": -100.0,
                "release-time": 120.0,
                "sidechain-custom-highcut-filter": false,
                "sidechain-custom-lowcut-filter": false,
                "sidechain-highcut-frequency": 4000.0,
                "sidechain-lookahead": 0.0,
                "sidechain-lowcut-frequency": 2000.0,
                "sidechain-mode": "RMS",
                "sidechain-preamp": 0.0,
                "sidechain-reactivity": 10.0,
                "sidechain-source": "Middle",
                "solo": false,
                "split-frequency": 5000.0,
                "stereo-split-source": "Left/Right"
            },
            "band4": {
                "attack-threshold": -12.0,
                "attack-time": 20.0,
                "boost-amount": 6.0,
                "boost-threshold": -72.0,
                "compression-mode": "Downward",
                "compressor-enable": true,
                "enable-band": false,
                "external-sidechain": false,
                "knee": -6.0,
                "makeup": 0.0,
                "mute": false,
                "ratio": 1.0,
                "release-threshold": -100.0,
                "release-time": 100.0,
                "sidechain-custom-highcut-filter": false,
                "sidechain-custom-lowcut-filter": false,
                "sidechain-highcut-frequency": 8000.0,
                "sidechain-lookahead": 0.0,
                "sidechain-lowcut-frequency": 4000.0,
                "sidechain-mode": "RMS",
                "sidechain-preamp": 0.0,
                "sidechain-reactivity": 10.0,
                "sidechain-source": "Middle",
                "solo": false,
                "split-frequency": 4000.0,
                "stereo-split-source": "Left/Right"
            },
            "band5": {
                "attack-threshold": -12.0,
                "attack-time": 20.0,
                "boost-amount": 6.0,
                "boost-threshold": -72.0,
                "compression-mode": "Downward",
                "compressor-enable": true,
                "enable-band": false,
                "external-sidechain": false,
                "knee": -6.0,
                "makeup": 0.0,
                "mute": false,
                "ratio": 1.0,
                "release-threshold": -100.0,
                "release-time": 100.0,
                "sidechain-custom-highcut-filter": false,
                "sidechain-custom-lowcut-filter": false,
                "sidechain-highcut-frequency": 12000.0,
                "sidechain-lookahead": 0.0,
                "sidechain-lowcut-frequency": 8000.0,
                "sidechain-mode": "RMS",
                "sidechain-preamp": 0.0,
                "sidechain-reactivity": 10.0,
                "sidechain-source": "Middle",
                "solo": false,
                "split-frequency": 8000.0,
                "stereo-split-source": "Left/Right"
            },
            "band6": {
                "attack-threshold": -12.0,
                "attack-time": 20.0,
                "boost-amount": 6.0,
                "boost-threshold": -72.0,
                "compression-mode": "Downward",
                "compressor-enable": true,
                "enable-band": false,
                "external-sidechain": false,
                "knee": -6.0,
                "makeup": 0.0,
                "mute": false,
                "ratio": 1.0,
                "release-threshold": -100.0,
                "release-time": 100.0,
                "sidechain-custom-highcut-filter": false,
                "sidechain-custom-lowcut-filter": false,
                "sidechain-highcut-frequency": 16000.0,
                "sidechain-lookahead": 0.0,
                "sidechain-lowcut-frequency": 12000.0,
                "sidechain-mode": "RMS",
                "sidechain-preamp": 0.0,
                "sidechain-reactivity": 10.0,
                "sidechain-source": "Middle",
                "solo": false,
                "split-frequency": 12000.0,
                "stereo-split-source": "Left/Right"
            },
            "band7": {
                "attack-threshold": -12.0,
                "attack-time": 20.0,
                "boost-amount": 6.0,
                "boost-threshold": -72.0,
                "compression-mode": "Downward",
                "compressor-enable": true,
                "enable-band": false,
                "external-sidechain": false,
                "knee": -6.0,
                "makeup": 0.0,
                "mute": false,
                "ratio": 1.0,
                "release-threshold": -100.0,
                "release-time": 100.0,
                "sidechain-custom-highcut-filter": false,
                "sidechain-custom-lowcut-filter": false,
                "sidechain-highcut-frequency": 20000.0,
                "sidechain-lookahead": 0.0,
                "sidechain-lowcut-frequency": 16000.0,
                "sidechain-mode": "RMS",
                "sidechain-preamp": 0.0,
                "sidechain-reactivity": 10.0,
                "sidechain-source": "Middle",
                "solo": false,
                "split-frequency": 16000.0,
                "stereo-split-source": "Left/Right"
            },
            "bypass": false,
            "compressor-mode": "Modern",
            "dry": -100.0,
            "envelope-boost": "None",
            "input-gain": 0.0,
            "output-gain": 0.0,
            "stereo-split": false,
            "wet": 0.0
        },
        "plugins_order": [
            "filter#0",
            "bass_enhancer#0",
            "convolver#0",
            "multiband_compressor#0",
            "stereo_tools#0",
            "limiter#0"
        ],
        "stereo_tools#0": {
            "balance-in": 0.0,
            "balance-out": 0.0,
            "bypass": false,
            "delay": 0.0,
            "input-gain": 0.0,
            "middle-level": 0.0,
            "middle-panorama": 0.0,
            "mode": "LR > LR (Stereo Default)",
            "mutel": false,
            "muter": false,
            "output-gain": 0.0,
            "phasel": false,
            "phaser": false,
            "sc-level": 1.0,
            "side-balance": 0.0,
            "side-level": 0.0,
            "softclip": false,
            "stereo-base": 0.30000000000000004,
            "stereo-phase": 0.0
        }
    }
}
1 Like

Awesome thread! I just set this up, and what a huge difference. Thanks for the simple script, cab. I went from stock audio to using gracefu’s preset, and I can’t believe I was living that way before! So much better!!

2 Likes

Just got to try it — it’s really nice! Bass indeed (IMO) sounds a lot better than on HifiScan+EEGuide preset — and I liked it more overall, so I am switching to it)

You can PR it to the repo, so people get it installed too! <3
Would be also nice to have this comment copied over to readme as a piece of documentation

If you want, I can just add it myself too

Thanks for the PR offer. You can add it yourself, it’s probably easier for everyone involved :slight_smile:

Done! Thank you :з

So I had one issue with this setup, and it was that it automatically applied the same enhancements to any headphones I plugged into the audio jack. The issue is that they are managed by the same audio device. I managed to solve that by taking advantage of the device-profile, which is shown in EasyEffects, but the GUI doesn’t give you any options to control things based on that… Perhaps this is obvious to some, but here are the steps I took.

First, I saved the enhancements to the speakers as an autoloading preset under the PipeWire tab in EasyEffects.
image

Next, under the Output tab, I disabled all the enhancements and saved that as a preset ‘Default (EE off)’. You could instead save any headphone enhancements you want to use. I haven’t gotten that far yet!

Then, I opened the directory in which those autoloading presets are saved, $HOME/.config/easyeffects/autoload/output/ and opened the corresponding file in a text editor. This was the file as saved by EasyEffects:

{
    "device": "alsa_output.pci-0000_c1_00.6.analog-stereo",
    "device-description": "Family 17h/19h HD Audio Controller Analog Stereo",
    "device-profile": "analog-output-speaker",
    "preset-name": "Best"
}

I just changed the last two lines as desired. Be sure to match the preset name exactly. (I was able to determine which device-profile was needed by running pactl list cards and looking at the Profiles section for the corresponding device.) Here’s the result of my changes:

{
    "device": "alsa_output.pci-0000_c1_00.6.analog-stereo",
    "device-description": "Family 17h/19h HD Audio Controller Analog Stereo",
    "device-profile": "analog-output-headphones",
    "preset-name": "Default (EE off)"
}

I saved that as a new .json file with the same name scheme as the others, device:device-profile.json. In my case it turned out as alsa_output.pci-0000_c1_00.6.analog-stereo:analog-output-headphones.json.

That was all it took, the software automatically disables enhancements for my headphones and enables them for speakers now! I’m delighted! I hope this is helpful.

2 Likes

Wow, I was making this way harder than it needed to be. I’m not sure how I didn’t notice, but the EasyEffects UI saves whatever device-profile is active at the time on the device when saving a preset, so it’s easy to save presets separately for headphones and speakers, or other audio devices.

I just tried out the script and in the first try got the error:
cp: Target ‘/home/<user>/.config/easyeffects’: File or Directory not found

So I created the target directory using ‘mkdir’ and ran it again without issues.
Would be nice if you could add that to the script to avoid that extra step.

EDIT: Looking a bit further into this issue I realized, that the reason for this directory missing was the fact, that I hadn’t installed EasyEffects to begin with.
Part of the reason was the absence of clear install instructions though (the rest being me rushing it).
Please provide clear install instructions at the top of your README to avoid such issues for new users to come.

Done :)

Thanks and sorry, I forgot to update my posting after looking further into this issue.

Looks like I didn’t have EasyEffects installed, because I thought the script would do everything needed, so my problem might have been avoided by installing it first. The README was very confusing to me in that regard. It would be advisable, to have a clear quick install instruction section at the top of the README to avoid any misunderstandings. :wink:

There is no universal quick install instruction for EasyEffects (there are many distros), so that’s left as an exercise for the reader :)

Still, it would have been helpful to users to mention inside the README, that EasyEffects has to be installed as a requirement. :wink:

As I’ve mentioned earlier, that I’ve done.

1 Like

Would you be willing to publish the repository under an open-source license?
I would like to statically configure this preset on my system via Nix (home-manager), and I have so far published my configuration publicly; for this to be able to include this preset there’d need to be a license that makes it redistributable.

This is just a request, you are free to deny it. I do though consider that it seems there’d be little downside to attaching a free license to the repository.


Since the repository includes code from @gracefu I’d need permission from you, too.

Does this still kill the battery life like crazy when running with it?