117 lines
3.5 KiB
Nix
117 lines
3.5 KiB
Nix
|
{ config, lib, pkgs, ... }:
|
||
|
|
||
|
with lib;
|
||
|
|
||
|
let
|
||
|
cfg = config;
|
||
|
speak = cfg.speak;
|
||
|
in rec {
|
||
|
options.speak = {
|
||
|
enable = mkOption {
|
||
|
type = types.bool;
|
||
|
default = false;
|
||
|
description = ''
|
||
|
Enable NixOS speak module.
|
||
|
'';
|
||
|
};
|
||
|
installPackages = mkOption {
|
||
|
type = types.bool;
|
||
|
default = true;
|
||
|
description = ''
|
||
|
Add spech related packages to environment.
|
||
|
'';
|
||
|
};
|
||
|
user = mkOption {
|
||
|
type = types.str;
|
||
|
default = "root";
|
||
|
description = ''
|
||
|
User which runs services like espeakup and speech-dispatcher.
|
||
|
User needs to be in audio group.
|
||
|
'';
|
||
|
};
|
||
|
config = {
|
||
|
speakup = mkOption {
|
||
|
type = types.attrs;
|
||
|
default = {};
|
||
|
example = ''
|
||
|
{
|
||
|
synth = "soft";
|
||
|
punc_level = "0";
|
||
|
reading_punc = "0";
|
||
|
soft = {
|
||
|
rate = "6";
|
||
|
};
|
||
|
}
|
||
|
'';
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
config = mkIf speak.enable rec {
|
||
|
boot.kernelModules = [ "speakup_soft" ];
|
||
|
nixpkgs.config.packageOverrides = {
|
||
|
espeakup = pkgs.callPackage ../pkgs/espeakup.nix {};
|
||
|
};
|
||
|
|
||
|
# needed for orca
|
||
|
services.gnome3.at-spi2-core.enable = mkDefault (cfg.services.xserver.enable);
|
||
|
|
||
|
# allow users in the audio group to use and configure speakup_soft
|
||
|
services.udev.extraRules = ''
|
||
|
KERNEL=="synth", SUBSYSTEM=="misc", GROUP="audio", MODE="0660"
|
||
|
KERNEL=="softsynth", SUBSYSTEM=="misc", GROUP="audio", MODE="0660"
|
||
|
KERNEL=="softsynthu", SUBSYSTEM=="misc", GROUP="audio", MODE="0660"
|
||
|
'';
|
||
|
|
||
|
# See https://aur.archlinux.org/cgit/aur.git/tree/espeakup.service?h=espeakup-git
|
||
|
systemd.services = {
|
||
|
speakup-configure = let
|
||
|
# This whole thing still feels a little bit awkward
|
||
|
pathList = collect (v: isList v) (mapAttrsRecursive (p: v: p) speak.config.speakup);
|
||
|
mkCommand = p: v: "echo ${v} > /sys/accessibility/speakup/${p}";
|
||
|
commandList = (map (l: (mkCommand (concatStringsSep "/" l) (attrByPath l "0" speak.config.speakup))) pathList);
|
||
|
in {
|
||
|
enable = true;
|
||
|
description = "configure speakup.";
|
||
|
wantedBy = [ "default.target" ];
|
||
|
wants = [ "systemd-udev-settle.service" ];
|
||
|
after = [ "systemd-udev-settle.service" "sound.target" ];
|
||
|
script = (concatStringsSep "\n" commandList);
|
||
|
serviceConfig.Type = "oneshot";
|
||
|
};
|
||
|
espeakup = {
|
||
|
enable = (speak.user == "root");
|
||
|
description = "Software speech output system wide settings.";
|
||
|
wantedBy = [ "default.target" ];
|
||
|
wants = [ "systemd-udev-settle.service" ];
|
||
|
after = [ "systemd-udev-settle.service" "sound.target" ];
|
||
|
|
||
|
serviceConfig = {
|
||
|
Type = "forking";
|
||
|
ExecStart = "${pkgs.espeakup}/bin/espeakup";
|
||
|
ExecStop = "${pkgs.utillinux.bin}/bin/kill -HUP $MAINPID";
|
||
|
Restart= "always";
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
systemd.user.services.espeakup = {
|
||
|
enable = (speak.user != "root");
|
||
|
description = "Software speech output system wide settings.";
|
||
|
wantedBy = [ "default.target" ];
|
||
|
wants = [ "systemd-udev-settle.service" ];
|
||
|
after = [ "systemd-udev-settle.service" "sound.target" ];
|
||
|
|
||
|
serviceConfig = {
|
||
|
Type = "forking";
|
||
|
ExecStart = "${pkgs.espeakup}/bin/espeakup";
|
||
|
ExecStop = "${pkgs.utillinux.bin}/bin/kill -HUP $MAINPID";
|
||
|
Restart= "always";
|
||
|
};
|
||
|
};
|
||
|
environment.systemPackages = optionals speak.installPackages (with pkgs; [
|
||
|
(lowPrio espeak-classic) espeak-ng
|
||
|
espeakup
|
||
|
]);
|
||
|
};
|
||
|
}
|