Skip to content

Commit c66b595

Browse files
Tenshockkhaneliman
authored andcommitted
easyeffects: support separate startup presets
1 parent e91d4c1 commit c66b595

5 files changed

Lines changed: 129 additions & 5 deletions

File tree

modules/services/easyeffects.nix

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,62 @@ let
99

1010
cfg = config.services.easyeffects;
1111

12-
presetOpts = lib.optionalString (cfg.preset != "") "--load-preset ${cfg.preset}";
12+
isSplitPreset = builtins.isAttrs cfg.preset;
13+
14+
selectedPresets =
15+
if isSplitPreset then lib.filterAttrs (_: preset: preset != "") cfg.preset else { };
16+
17+
presetOpts = lib.optionalString (
18+
!isSplitPreset && cfg.preset != ""
19+
) "--load-preset ${lib.escapeShellArg cfg.preset}";
1320

1421
olderThan8 = lib.versionOlder cfg.package.version "8.0.0"; # This version introduces breaking changes and this check is used to stay backwards compatible
1522

23+
olderThan8_0_9 = lib.versionOlder cfg.package.version "8.0.9";
24+
1625
jsonFormat = pkgs.formats.json { };
1726

27+
splitPresetType = types.submodule {
28+
options = {
29+
input = mkOption {
30+
type = types.str;
31+
default = "";
32+
description = "Input preset to load when starting EasyEffects.";
33+
};
34+
35+
output = mkOption {
36+
type = types.str;
37+
default = "";
38+
description = "Output preset to load when starting EasyEffects.";
39+
};
40+
};
41+
};
42+
43+
splitPresetCommands = lib.concatStringsSep "\n" (
44+
lib.mapAttrsToList (
45+
pipeline: preset: "printf '%s\\n' ${lib.escapeShellArg "load_preset:${pipeline}:${preset}"}"
46+
) selectedPresets
47+
);
48+
49+
loadSplitPresets = pkgs.writeShellScript "easyeffects-load-presets" ''
50+
preset_socket=$1
51+
52+
for _ in {1..100}; do
53+
if [[ -S "$preset_socket" ]]; then
54+
if {
55+
:
56+
${splitPresetCommands}
57+
} | ${pkgs.socat}/bin/socat -u -T 1 - UNIX-CONNECT:"$preset_socket"; then
58+
exit 0
59+
fi
60+
fi
61+
62+
${pkgs.coreutils}/bin/sleep 0.1
63+
done
64+
65+
exit 1
66+
'';
67+
1868
settingType = types.nullOr (
1969
types.oneOf [
2070
types.bool
@@ -142,11 +192,23 @@ in
142192
package = lib.mkPackageOption pkgs "easyeffects" { };
143193

144194
preset = mkOption {
145-
type = types.str;
195+
type = types.either types.str splitPresetType;
146196
default = "";
197+
example = literalExpression ''
198+
{
199+
input = "voice";
200+
output = "music";
201+
}
202+
'';
147203
description = ''
148-
Which preset to use when starting easyeffects.
149-
Will likely need to launch easyeffects to initially create preset.
204+
Preset to load when starting EasyEffects.
205+
206+
A string loads every input or output preset having that name. An
207+
attribute set selects input and output presets independently and
208+
requires EasyEffects 8.0.9 or later. An empty string leaves that
209+
pipeline unchanged.
210+
211+
You will likely need to launch EasyEffects to initially create presets.
150212
'';
151213
};
152214

@@ -179,6 +241,14 @@ in
179241
assertion = !hasSettings || !olderThan8;
180242
message = "${settingsOption} requires EasyEffects 8.0.0 or later.";
181243
}
244+
{
245+
assertion = !isSplitPreset || !olderThan8_0_9;
246+
message = "Structured `services.easyeffects.preset` requires EasyEffects 8.0.9 or later.";
247+
}
248+
{
249+
assertion = !isSplitPreset || selectedPresets != { };
250+
message = "Structured `services.easyeffects.preset` must select at least one input or output preset.";
251+
}
182252
];
183253

184254
home.packages = with pkgs; lib.optional olderThan8 at-spi2-core ++ [ cfg.package ]; # Only include if easyeffects version is below 8.0.0
@@ -222,6 +292,9 @@ in
222292
// lib.optionalAttrs hasSettings {
223293
ExecStartPre = settingsScript;
224294
}
295+
// lib.optionalAttrs isSplitPreset {
296+
ExecStartPost = "-${loadSplitPresets} %t/EasyEffectsServer";
297+
}
225298
// (
226299
if olderThan8 then
227300
{

tests/modules/services/easyeffects/default.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
55
easyeffects-example-preset = ./example-preset.nix;
66
easyeffects-null-presets = ./null-presets.nix;
77
easyeffects-settings-old-version = ./settings-old-version.nix;
8+
easyeffects-split-presets = ./split-presets.nix;
9+
easyeffects-split-presets-old-version = ./split-presets-old-version.nix;
810
}

tests/modules/services/easyeffects/service.nix

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ in
1111
{
1212
services.easyeffects = {
1313
enable = true;
14+
preset = "music";
1415
inherit settings;
1516
};
1617

@@ -20,7 +21,8 @@ in
2021
serviceFile=home-files/.config/systemd/user/easyeffects.service
2122
2223
assertFileExists $serviceFile
23-
assertFileRegex $serviceFile 'ExecStart=.*/bin/easyeffects'
24+
assertFileRegex $serviceFile \
25+
'ExecStart=.*/bin/easyeffects .*--load-preset music'
2426
assertFileContains $serviceFile \
2527
'X-Restart-Triggers=${builtins.hashString "sha256" (builtins.toJSON settings)}'
2628
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{ config, ... }:
2+
3+
{
4+
services.easyeffects = {
5+
enable = true;
6+
package = config.lib.test.mkStubPackage { version = "8.0.8"; };
7+
preset.input = "home";
8+
};
9+
10+
test.asserts.assertions.expected = [
11+
"Structured `services.easyeffects.preset` requires EasyEffects 8.0.9 or later."
12+
];
13+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{ config, ... }:
2+
3+
{
4+
services.easyeffects = {
5+
enable = true;
6+
package = config.lib.test.mkStubPackage { version = "8.0.9"; };
7+
preset = {
8+
input = "home";
9+
output = "Discord Voice";
10+
};
11+
};
12+
13+
test.stubs.easyeffects = { };
14+
15+
nmt.script = ''
16+
serviceFile=home-files/.config/systemd/user/easyeffects.service
17+
18+
assertFileExists "$serviceFile"
19+
assertFileNotRegex "$serviceFile" 'ExecStart=.*--load-preset'
20+
assertFileRegex "$serviceFile" \
21+
'ExecStartPost=.*-easyeffects-load-presets %t/EasyEffectsServer'
22+
23+
presetLoader=$(sed -n \
24+
's|^ExecStartPost=-\([^ ]*\).*|\1|p' "$TESTED/$serviceFile")
25+
26+
assertFileExists "$presetLoader"
27+
assertFileContains "$presetLoader" \
28+
"printf '%s\\n' load_preset:input:home"
29+
assertFileContains "$presetLoader" \
30+
"printf '%s\\n' 'load_preset:output:Discord Voice'"
31+
assertFileContains "$presetLoader" \
32+
'socat -u -T 1 - UNIX-CONNECT:"$preset_socket"'
33+
'';
34+
}

0 commit comments

Comments
 (0)