Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pipewire, unable to set up filter chain via configuration.nix #193176

Closed
mabequinho opened this issue Sep 27, 2022 · 5 comments
Closed

Pipewire, unable to set up filter chain via configuration.nix #193176

mabequinho opened this issue Sep 27, 2022 · 5 comments

Comments

@mabequinho
Copy link

Describe the bug

Unable to set filter chain via configuration.nix although it works if i put on ~/.config/pipewire/

Steps To Reproduce

Steps to reproduce the behavior:

  1. add a libpipewire-module-filter-chain block inside context.modules via option services.pipewire.config.pipewire.

pipewireconfnix.txt

Expected behavior

Add a extra sound imput(Noise Canceling source).

Additional context

could be related to upgrade from pipewire 0.3.54 to 0.3.55 breaks rnnoise filter

× pipewire.service - PipeWire Multimedia Service
     Loaded: loaded (/etc/systemd/user/pipewire.service; linked-runtime; preset: enabled)
    Drop-In: /nix/store/khly40xfd1j3kdq3hj1s728sbxnx4xn1-user-units/pipewire.service.d
             └─overrides.conf
     Active: failed (Result: exit-code) since Tue 2022-09-27 09:58:18 -03; 15s ago
   Duration: 18ms
TriggeredBy: × pipewire.socket
    Process: 21658 ExecStart=/nix/store/85bkqah1kxikn0cqmxs3d0q4n527b9g5-pipewire-0.3.56/bin/pipewire (code=exited, status=161)
   Main PID: 21658 (code=exited, status=161)
        CPU: 18ms

set 27 09:58:18 inferno systemd[1142]: pipewire.service: Scheduled restart job, restart counter is at 5.
set 27 09:58:18 inferno systemd[1142]: Stopped PipeWire Multimedia Service.
set 27 09:58:18 inferno systemd[1142]: pipewire.service: Start request repeated too quickly.
set 27 09:58:18 inferno systemd[1142]: pipewire.service: Failed with result 'exit-code'.
set 27 09:58:18 inferno systemd[1142]: Failed to start PipeWire Multimedia Service.
[E][02881.509507] pw.core      | [          core.c:  382 core_new()] 0x557bbb8330e0: can't find protocol 'PipeWire:Protocol:Native': Operation not supported
[E][02881.509582] mod.filter-chain | [module-filter-ch: 2235 pipewire__module_init()] can't connect: Operation not supported
[E][02881.509791] pw.conf      | [          conf.c:  560 load_module()] 0x557bbb7cd710: could not load mandatory module "libpipewire-module-filter-chain": Operation not supported
[E][02881.509864] default      | [      pipewire.c:  125 main()] failed to create context: Operation not supported

Notify maintainers

Metadata

 - system: `"x86_64-linux"`
 - host os: `Linux 5.19.9, NixOS, 22.11 (Raccoon), 22.11pre411253.79d3ca08920`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.11.0`
 - channels(lucio): `""`
 - channels(root): `"nixos"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`

@jansol
Copy link
Contributor

jansol commented Sep 28, 2022

I have used this for quite a while without problems:

{ config, pkgs, ... }:
let
  json = pkgs.formats.json {};
  pw_rnnoise_config = {
    "context.properties" = {
      "log.level" = 0;
    };
    "context.spa-libs" = {
      "audio.convert.*" = "audioconvert/libspa-audioconvert";
      "support.*" = "support/libspa-support";
    };
    "context.modules" = [
      {
        name = "libpipewire-module-rtkit";
        args = {
          #"nice.level"   = -11;
          #"rt.prio"      = 88;
          #"rt.time.soft" = 2000000;
          #"rt.time.hard" = 2000000;
        };
        flags = [ "ifexists" "nofail" ];
      }
      { name = "libpipewire-module-protocol-native"; }
      { name = "libpipewire-module-client-node"; }
      { name = "libpipewire-module-adapter"; }


      {
        name = "libpipewire-module-filter-chain";
        args = {
          "node.name"        = "effect_input.rnnoise";
          "node.description" = "Noise Canceling source";
          "media.name"       = "Noise Canceling source";
          "filter.graph" = {
            nodes = [
              {
                type   = "ladspa";
                name   = "rnnoise";
                plugin = "librnnoise_ladspa";
                label  = "noise_suppressor_mono";
                control = {
                  "VAD Threshold (%)" = 50.0;
                 };
              }
            ];
          };
          "capture.props" = {
            "node.passive" = true;
	    "node.target" = "alsa_input.usb-M-Audio_Fast_Track-00.pro-input-0";
	    "audio.position" = [ "AUX0" ];
          };
          "playback.props" = {
	    "audio.position" = [ "MONO" ];
            "media.class" = "Audio/Source";
          };
        };
      }
    ];
  };
in
{
  environment.etc."pipewire/source-rnnoise.conf" = {
      source = json.generate "source-rnnoise.conf" pw_rnnoise_config;
  };
  systemd.user.services."pipewire-source-rnnoise" = {
    environment = { LADSPA_PATH = "${pkgs.rnnoise-plugin}/lib/ladspa"; };
    description = "Noise canceling source for pipewire";
    wantedBy = ["pipewire.service"];
    script = "${pkgs.pipewire}/bin/pipewire -c source-rnnoise.conf";
    enable = true;
    path = with pkgs; [pipewire rnnoise-plugin];
  };
}

@mabequinho
Copy link
Author

mabequinho commented Sep 30, 2022

You know if something like this would be enough? Since pipewire now can use split conf files I think it could work if there´s a way to generate the /etc/pipewire/pipewire.conf.d/99-input-denoising.conf without the leading and trailing brackets.

I´m trying to make something like this https://github.com/werman/noise-suppression-for-voice

let
  json = pkgs.formats.json {};
  pw_rnnoise_config = {

  "context.modules"= [

###MICFILTER
    { "name" = "libpipewire-module-filter-chain";
        "args" = {
            "node.description" = "Noise Canceling source";
            "media.name"       = "Noise Canceling source";
            "filter.graph" = {
                "nodes" = [
                    {
                        "type"   = "ladspa";
                        "name"   = "rnnoise";
                        "plugin" = "${pkgs.rnnoise-plugin}/lib/ladspa/librnnoise_ladspa.so";
                        "label"  = "noise_suppressor_stereo";
                        "control" = {
                            "VAD Threshold (%)" = 50.0;
                        };
                    }
                ];
            };
            "audio.position" = [ "FL" "FR" ];
            "capture.props" = {
                "node.name" = "effect_input.rnnoise";
                "node.passive" = true;
            };
            "playback.props" = {
                "node.name" = "effect_output.rnnoise";
                "media.class" = "Audio/Source";
            };
        };
    }
];

  };
in
{
  environment.etc."pipewire/pipewire.conf.d/99-input-denoising.conf" = {
      source = json.generate "99-input-denoising.conf" pw_rnnoise_config;
  };
}

@mabequinho
Copy link
Author

nvmd, its working this way, you you enlightened me, thnx.

{ config, pkgs, ... }:
{
  sound.enable = true;
  hardware.pulseaudio.enable = false;
  security.rtkit.enable = true;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
	};
}
{ config, pkgs, ... }:

let
  json = pkgs.formats.json {};
  pw_rnnoise_config = {
  "context.modules"= [
    { "name" = "libpipewire-module-filter-chain";
        "args" = {
            "node.description" = "Noise Canceling source";
            "media.name"       = "Noise Canceling source";
            "filter.graph" = {
                "nodes" = [
                    {
                        "type"   = "ladspa";
                        "name"   = "rnnoise";
                        "plugin" = "${pkgs.rnnoise-plugin}/lib/ladspa/librnnoise_ladspa.so";
                        "label"  = "noise_suppressor_stereo";
                        "control" = {
                            "VAD Threshold (%)" = 50.0;
                        };
                    }
                ];
            };
            "audio.position" = [ "FL" "FR" ];
            "capture.props" = {
                "node.name" = "effect_input.rnnoise";
                "node.passive" = true;
            };
            "playback.props" = {
                "node.name" = "effect_output.rnnoise";
                "media.class" = "Audio/Source";
            };
        };
    }
];
};
in
{
  environment.etc."pipewire/pipewire.conf.d/99-input-denoising.conf" = {
      source = json.generate "99-input-denoising.conf" pw_rnnoise_config;
		};
}

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/pipewire-unable-to-set-filter-chain-via-configuration-nix/21972/4

@jansol
Copy link
Contributor

jansol commented Oct 1, 2022

@wnxkiv85 That log fragment you posted says that it hasn't loaded libpipewire-module-protocol-native yet, and filter-chain depends on that. It used to be a very common issue that you had to have the modules listed in your config in a specific order but I got the impression that they had removed that limitation.

Maybe that is what the regression is about. The separate config fragments presumably get processed only after the main config file so the dependencies are already loaded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants