nixos-config/nixos/modules/system/audio.nix

171 lines
4.5 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
ladspaPath = "${pkgs.ladspaPlugins}/lib/ladspa";
jackScript =
pkgs.writeShellScriptBin "jack" (lib.fileContents ../../assets/jack.sh);
queueElement = {
options = {
plugin = mkOption {
type = with types; str;
description = "file name without suffix of the plugin";
};
label = mkOption {
type = with types; str;
description = "label of the queue element (needs to be correct)";
};
control = mkOption {
type = with types; listOf str;
description = "parameter of plugin";
};
};
};
sinkElement = {
options = {
name = mkOption {
type = with types; str;
description = "name of the sink";
};
queue = mkOption {
type = with types; listOf (submodule queueElement);
description = "queues";
};
};
};
cfg = config.system.custom.audio;
in
{
options.system.custom.audio = {
enable = mkEnableOption "use PluseAudio";
sinks = mkOption {
type = with types; listOf (submodule sinkElement);
description = "list of sinks";
};
};
config = mkIf cfg.enable {
# add virtual midi module
# -----------------------
#boot = {
# # to route midi signals
# # between bitwig and vcvrack
# kernelModules = [ "snd_virmidi" ];
# # index=-2 prevents from beeing recognised as the default
# # audio device
# # midi_devs limit the number of midi devices.
# extraModprobeConfig = "options snd-virmidi index=-2 midi_devs=1";
#};
# LADSPA
# ------
programs.bash.interactiveShellInit = # sh
''
# set ladspa library path
# about testing the plugins check analyseplugin command
export LADSPA_PATH=${ladspaPath}
'';
programs.zsh.interactiveShellInit = # sh
''
# set ladspa library path
# about testing the plugins check analyseplugin command
export LADSPA_PATH=${ladspaPath}
'';
# PulseAudio
# ----------
# because of systemWide ensure main user is in audio group
system.custom.mainUser.extraGroups = [ "audio" "pipewire" ];
#services.pipewire = {
# enable = true;
# systemWide = true;
# media-session.enable = false;
# pulse.enable = true;
# jack.enable = false;
# alsa.enable = false;
#};
#hardware.pulseaudio.enable = false;
# todo use pipewire for this
hardware.pulseaudio = {
enable = true;
package = pkgs.pulseaudioFull;
# all in audio group can do audio
systemWide = true;
extraConfig = ''
# automatically switch to newly-connected devices
load-module module-switch-on-connect
# http://plugin.org.uk/ladspa-swh/docs/ladspa-swh.html
# https://gavv.github.io/articles/pulseaudio-under-the-hood/#ladspa-plugin-sink
${builtins.toString (flip map cfg.sinks (sink: ''
# ladspa sink : ${sink.name}
# -------------
${builtins.toString (flip imap0 (reverseList sink.queue)
(index: queua:
let
sinkName = suffix: "${sink.name}${builtins.toString suffix}";
sinkValue = "sink_name=${sinkName index}";
sinkDescription = "sink_properties=device.description=${
sinkName index
}-${queua.label}";
masterValue = if (index == 0) then
""
else
"sink_master=${sinkName (index - 1)}";
pluginValue = "plugin=${ladspaPath}/${queua.plugin}";
labelValue = "label=${queua.label}";
controlValue = "control=${
builtins.toString
(foldl (a: b: "${a},${b}") (head queua.control)
(tail queua.control))
}";
in ''
# ${sinkName index} : ${queua.label}
load-module module-ladspa-sink ${sinkValue} ${sinkDescription} ${masterValue} ${pluginValue} ${labelValue} ${controlValue}
''))}
''))}
'';
};
# Packages needed
# ---------------
environment.systemPackages = with pkgs; [
# Music making
# ------------
#jackScript
#jack2Full
#patchage
#zynaddsubfx
#qjackctl
alsaUtils
# LADSPA
# ------
ladspaPlugins
ladspa-sdk
# PulseAudio control
# ------------------
pavucontrol
lxqt.pavucontrol-qt
];
};
}