diff --git a/.gitignore b/.gitignore index 5cc7a0c..0290c36 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ dist *.egg-info __pycache__ .venv -*.wav \ No newline at end of file +*.wav +result \ No newline at end of file diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..199ddcc --- /dev/null +++ b/default.nix @@ -0,0 +1,62 @@ +{ lib, python311Packages }: +with python311Packages; +let + # Stripped down version of the tts package (original is broken and needs cuda) + tts = + let + pname = "TTS"; + version = "0.22.0"; + in + buildPythonPackage { + inherit pname version; + src = pkgs.fetchPypi { + inherit pname version; + sha256 = "sha256-uREZ2n/yrns9rnMo7fmvTbO0jEDrTOFdEe2PXum9cIY="; + }; + doCheck = false; + + dependencies = [ + cython + numpy + torch + torchaudio + coqpit + trainer + pysbd + pandas + matplotlib + anyascii + inflect + bangla + bnnumerizer + bnunicodenormalizer + gruut + jamo + jieba + pypinyin + ]; + }; +in +buildPythonApplication { + pname = "mensa-tts"; + version = "1.0"; + pyproject = true; + src = ./.; + + build-system = [ + setuptools + setuptools-scm + ]; + + dependencies = [ + requests + tts + librosa + ]; + + meta = with lib; { + description = "Satnogs Demo Display"; + homepage = "https://forgejo.zenerdio.de/sebastian/satnogs-demo-display"; + platforms = platforms.unix; + }; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..d22a24f --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1734323986, + "narHash": "sha256-m/lh6hYMIWDYHCAsn81CDAiXoT3gmxXI9J987W5tZrE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "394571358ce82dff7411395829aa6a3aad45b907", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..404603c --- /dev/null +++ b/flake.nix @@ -0,0 +1,44 @@ +{ + description = "A flake for the mensa-tts system."; + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; + }; + + + outputs = inputs@{ self, nixpkgs, ... }: + let + lib = nixpkgs.lib; + + allSystems = [ "x86_64-linux" "aarch64-linux" "armv6l-linux" ]; + + crossPkgs-aarch64-linux = import nixpkgs { localSystem = "x86_64-linux"; crossSystem = "aarch64-linux"; }; + crossPkgs-armv6l-linux = import nixpkgs { + localSystem = "x86_64-linux"; + crossSystem = { + system = "armv6l-linux"; + gcc = { + arch = "armv6k"; + fpu = "vfp"; + }; + }; + }; + in + { + formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.nixpkgs-fmt; + + packages = { + x86_64-linux = { + default = nixpkgs.legacyPackages.x86_64-linux.callPackage ./default.nix { }; + cross-aarch64-linux = crossPkgs-aarch64-linux.callPackage ./default.nix { }; + cross-armv6l-linux = crossPkgs-armv6l-linux.callPackage ./default.nix { }; + }; + aarch64-linux.default = nixpkgs.legacyPackages.aarch64-linux.callPackage ./default.nix { }; + armv6l-linux.default = nixpkgs.legacyPackages.armv6l-linux.callPackage ./default.nix { }; + }; + + nixosModules.default = { config, pkgs, ... }: { + imports = [ ./module.nix ]; + _module.args.mensa-tts-pkgs = self.packages; + }; + }; +} diff --git a/mensa.wav b/mensa.wav deleted file mode 100644 index 9441639..0000000 Binary files a/mensa.wav and /dev/null differ diff --git a/module.nix b/module.nix new file mode 100644 index 0000000..c48afef --- /dev/null +++ b/module.nix @@ -0,0 +1,117 @@ +{ lib, config, pkgs, mesa-tts-pkgs, ... }: +with lib; +let + # Shorter name to access final settings a + # user of hello.nix module HAS ACTUALLY SET. + # cfg is a typical convention. + cfg = config.services.mesa-tts; +in +{ + + options.services.mesa-tts = { + enable = mkEnableOption "mensa-tts service"; + + package = mkOption { + default = mesa-tts-pkgs.x86_64-linux.default; + type = types.package; + description = "mensa-tts packages to use. Needed to fix crosscompilation issues."; + }; + + user = mkOption { + type = types.str; + default = "mensa-tts"; + description = mdDoc "User to run the mensa-tts script."; + }; + + group = mkOption { + type = types.str; + default = "mensa-tts"; + description = mdDoc "Group for the mensa-tts user."; + }; + + time = mkOption { + type = types.str; + default = "Mon..Fri 11:10:00 Europe/Berlin"; + description = mdDoc "Time to trigger the mensa-tts service. Uses systemd OnCalendar format."; + }; + + local-address = mkOption { + type = types.str; + default = "127.0.0.1"; + description = mdDoc "Local address to send the UDP frames from"; + }; + + local-port = mkOption { + type = types.str; + default = "4810"; + description = mdDoc "Local port to send the UDP frames from"; + }; + + remote-address = mkOption { + type = types.str; + default = "127.0.0.1"; + description = mdDoc "Remote address to send the UDP frames to"; + }; + + remote-port = mkOption { + type = types.str; + default = "3810"; + description = mdDoc "Remote port to send the UDP frames to"; + }; + + cache-dir = mkOption { + type = types.str; + default = "/var/cache/mensa-tts"; + description = mdDoc "Directory to store temporary data"; + }; + + }; + + config = mkIf cfg.enable { + environment.systemPackages = with pkgs; [ + cfg.package + ]; + + users.users = mkIf (cfg.user == "mensa-tts") { + mensa-tts = { + group = cfg.group; + isNormalUser = true; + }; + }; + + users.groups = mkIf (cfg.group == "mensa-tts") { + mensa-tts = { }; + }; + + systemd.tmpfiles.rules = [ + "d '${cfg.cache-dir}' 0750 ${cfg.user} ${cfg.group} - -" + ]; + + systemd.services.mesa-tts = { + description = "mesa-tts service"; + serviceConfig = { + Type = "oneshot"; + User = cfg.user; + Group = cfg.group; + WorkingDirectory = cfg.cache-dir; + }; + script = '' + ${cfg.package}/bin/mena-tts + ${cfg.package}/bin/fm_feed_wav --local-addr ${cfg.local-address} \ + --local-port ${cfg.local-port} \ + --local-addr ${cfg.local-address} \ + --local-port ${cfg.local-port} \ + --wav mensa.wav + ''; + }; + + + systemd.timers.mesa-tts = { + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = cfg.time; + Unit = "mesa-tts.service"; + }; + }; + }; +}