ft: moved cables.sh into nix
This commit is contained in:
125
modules/audio/default.nix
Normal file
125
modules/audio/default.nix
Normal file
@@ -0,0 +1,125 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
linkSinksScript = pkgs.writeShellApplication {
|
||||
name = "link-virtual-sinks";
|
||||
runtimeInputs = with pkgs; [
|
||||
coreutils
|
||||
gnugrep
|
||||
pipewire
|
||||
];
|
||||
runtimeEnv = {
|
||||
USB_C_SINK = "alsa_output.usb-HP__Inc_HyperX_Cloud_III_Wireless_0000000000000000-00.analog-stereo";
|
||||
};
|
||||
text = builtins.readFile ./linkSinks.sh;
|
||||
};
|
||||
in
|
||||
{
|
||||
services.pulseaudio.enable = false;
|
||||
security.rtkit.enable = true;
|
||||
|
||||
services.pipewire = {
|
||||
enable = true;
|
||||
alsa.enable = true;
|
||||
alsa.support32Bit = true;
|
||||
pulse.enable = true;
|
||||
jack.enable = true;
|
||||
|
||||
# disable automatic gain control for specific apps
|
||||
extraConfig.pipewire-pulse."10-block-source-volume.conf"."pulse.rules" = [
|
||||
{
|
||||
matches = [
|
||||
{ "application.name" = "~Chromium.*"; }
|
||||
{ "application.process.binary" = "Discord"; }
|
||||
{ "application.process.binary" = "vesktop"; }
|
||||
# TODO: add element to this list
|
||||
];
|
||||
actions.quirks = [ "block-source-volume" ];
|
||||
}
|
||||
];
|
||||
|
||||
extraConfig.pipewire."91-virtual-sinks" = {
|
||||
"context.objects" = [
|
||||
{
|
||||
factory = "adapter";
|
||||
args = {
|
||||
"factory.name" = "support.null-audio-sink";
|
||||
"node.name" = "game";
|
||||
"node.description" = "game";
|
||||
"media.class" = "Audio/Sink";
|
||||
"audio.position" = "FL,FR";
|
||||
};
|
||||
}
|
||||
{
|
||||
factory = "adapter";
|
||||
args = {
|
||||
"factory.name" = "support.null-audio-sink";
|
||||
"node.name" = "clementine";
|
||||
"node.description" = "clementine";
|
||||
"media.class" = "Audio/Sink";
|
||||
"audio.position" = "FL,FR";
|
||||
};
|
||||
}
|
||||
{
|
||||
factory = "adapter";
|
||||
args = {
|
||||
"factory.name" = "support.null-audio-sink";
|
||||
"node.name" = "element";
|
||||
"node.description" = "element";
|
||||
"media.class" = "Audio/Sink";
|
||||
"audio.position" = "FL,FR";
|
||||
};
|
||||
}
|
||||
{
|
||||
factory = "adapter";
|
||||
args = {
|
||||
"factory.name" = "support.null-audio-sink";
|
||||
"node.name" = "combine";
|
||||
"node.description" = "combine";
|
||||
"media.class" = "Audio/Sink";
|
||||
"audio.position" = "FL,FR";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
wireplumber.extraConfig."91-default-sink" = {
|
||||
"wireplumber.settings" = {
|
||||
"default.audio.sink" = "combine";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
programs.nix-ld.libraries = [ pkgs.pipewire ];
|
||||
|
||||
systemd.user.services.link-virtual-sinks = {
|
||||
description = "Link virtual PipeWire sinks";
|
||||
|
||||
wantedBy = [ "graphical-session.target" ];
|
||||
wants = [
|
||||
"pipewire.service"
|
||||
"wireplumber.service"
|
||||
];
|
||||
after = [
|
||||
"pipewire.service"
|
||||
"wireplumber.service"
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${linkSinksScript}/bin/link-virtual-sinks";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
};
|
||||
|
||||
# home-manager.users.djai.home.packages = with pkgs; [
|
||||
# pavucontrol
|
||||
# qpwgraph
|
||||
# ];
|
||||
|
||||
users.users.djai.packages = with pkgs; [
|
||||
pavucontrol
|
||||
pipewire
|
||||
qpwgraph
|
||||
];
|
||||
}
|
||||
40
modules/audio/linkSinks.sh
Executable file
40
modules/audio/linkSinks.sh
Executable file
@@ -0,0 +1,40 @@
|
||||
# wait until pw-link port becomes available
|
||||
# $1: port identifier
|
||||
wait_for_port() {
|
||||
for _ in $(seq 1 10); do
|
||||
if pw-link -io 2>/dev/null | grep -Fq "$1"; then
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
echo "Timed out waiting for PipeWire port: $1" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
# link two pipewire ports together. waits for htme to exist first.
|
||||
# $1: output port
|
||||
# $2: input port
|
||||
link_ports() {
|
||||
wait_for_port "$1"
|
||||
wait_for_port "$2"
|
||||
|
||||
# pw-link errors if a link already exists, but we don't want that to fail the script
|
||||
pw-link "$1" "$2" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# link clementine -> combine
|
||||
link_ports "clementine:monitor_FL" "combine:playback_FL"
|
||||
link_ports "clementine:monitor_FR" "combine:playback_FR"
|
||||
|
||||
# link element -> combine
|
||||
link_ports "element:monitor_FL" "combine:playback_FL"
|
||||
link_ports "element:monitor_FR" "combine:playback_FR"
|
||||
|
||||
# link game -> combine
|
||||
link_ports "game:monitor_FL" "combine:playback_FL"
|
||||
link_ports "game:monitor_FR" "combine:playback_FR"
|
||||
|
||||
# link combine -> usb_c_sink
|
||||
link_ports "combine:monitor_FL" "$USB_C_SINK:playback_FL"
|
||||
link_ports "combine:monitor_FR" "$USB_C_SINK:playback_FR"
|
||||
|
||||
Reference in New Issue
Block a user