From 88158a172b3555e8765bb0b1926c7e1dbb338386 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Wed, 27 Sep 2023 04:22:55 +0200 Subject: [PATCH 1/6] python311Packages.wyoming: 1.1.0 -> 1.2.0 --- pkgs/development/python-modules/wyoming/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/development/python-modules/wyoming/default.nix b/pkgs/development/python-modules/wyoming/default.nix index feb7106c513c..ccdb4908729d 100644 --- a/pkgs/development/python-modules/wyoming/default.nix +++ b/pkgs/development/python-modules/wyoming/default.nix @@ -5,12 +5,12 @@ buildPythonPackage rec { pname = "wyoming"; - version = "1.1.0"; + version = "1.2.0"; format = "setuptools"; src = fetchPypi { inherit pname version; - hash = "sha256-I5GgDu9HRj6fIX66q3RuDeB13h6dpwxrSBxKhzE+Fus="; + hash = "sha256-mgNhc8PMRrwfvGZEcgIvQ/P2dysdDo2juvZccvb2C/g="; }; pythonImportsCheck = [ From 6c8832e2b88a966909ab5c674fc2ace6d9e0fdea Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Wed, 27 Sep 2023 04:35:11 +0200 Subject: [PATCH 2/6] wyoming-piper: 1.2.0 -> 1.3.2 --- pkgs/tools/audio/wyoming/piper.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/tools/audio/wyoming/piper.nix b/pkgs/tools/audio/wyoming/piper.nix index c5ce6f99005b..fbc52a88aa20 100644 --- a/pkgs/tools/audio/wyoming/piper.nix +++ b/pkgs/tools/audio/wyoming/piper.nix @@ -5,13 +5,13 @@ python3.pkgs.buildPythonApplication rec { pname = "wyoming-piper"; - version = "1.2.0"; + version = "1.3.2"; format = "setuptools"; src = fetchPypi { pname = "wyoming_piper"; inherit version; - hash = "sha256-cdCWpejHNCjyYtIxGms9yaEerRmFnGllUN7+3uQy4mQ="; + hash = "sha256-WyoHwIF3xC5nOa7iQ8/esfdwahbU6YJzK5G2Vi3mV4M="; }; patches = [ From e75579e566709d3adaa52e72015fd9522dfc435a Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Wed, 27 Sep 2023 05:08:37 +0200 Subject: [PATCH 3/6] python311Packages.webrtc-noise-gain: init at 1.2.0 Tiny wrapper around webrtc-audio-processing for noise suppression/auto gain only. https://github.com/rhasspy/webrtc-noise-gain --- .../webrtc-noise-gain/default.nix | 56 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 + 2 files changed, 58 insertions(+) create mode 100644 pkgs/development/python-modules/webrtc-noise-gain/default.nix diff --git a/pkgs/development/python-modules/webrtc-noise-gain/default.nix b/pkgs/development/python-modules/webrtc-noise-gain/default.nix new file mode 100644 index 000000000000..52b1d1fde48a --- /dev/null +++ b/pkgs/development/python-modules/webrtc-noise-gain/default.nix @@ -0,0 +1,56 @@ +{ lib +, buildPythonPackage +, fetchFromGitHub +, stdenv + +# build-system +, pybind11 +, setuptools + +# native dependencies +, abseil-cpp +, darwin + +# tests +, pytestCheckHook +}: + +buildPythonPackage rec { + pname = "webrtc-noise-gain"; + version = "1.2.2"; + pyproject = true; + + src = fetchFromGitHub { + owner = "rhasspy"; + repo = "webrtc-noise-gain"; + rev = "v${version}"; + hash = "sha256-yHuCa2To9/9kD+tLG239I1aepuhcPUV4a4O1TQtBPlE="; + }; + + nativeBuildInputs = [ + pybind11 + setuptools + ]; + + buildInputs = [ + abseil-cpp + ] ++ lib.optionals (stdenv.isDarwin) [ + darwin.apple_sdk.frameworks.CoreServices + ]; + + pythonImportsCheck = [ + "webrtc_noise_gain" + ]; + + nativeCheckInputs = [ + pytestCheckHook + ]; + + meta = with lib; { + description = "Tiny wrapper around webrtc-audio-processing for noise suppression/auto gain only"; + homepage = "https://github.com/rhasspy/webrtc-noise-gain"; + changelog = "https://github.com/rhasspy/webrtc-noise-gain/blob/${src.rev}/CHANGELOG.md"; + license = licenses.mit; + maintainers = with maintainers; [ hexa ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index fdf90d36ba3d..cf7d72b5347d 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -13929,6 +13929,8 @@ self: super: with self; { weboob = callPackage ../development/python-modules/weboob { }; + webrtc-noise-gain = callPackage ../development/python-modules/webrtc-noise-gain { }; + webrtcvad = callPackage ../development/python-modules/webrtcvad { }; websocket-client = callPackage ../development/python-modules/websocket-client { }; From 2f8cdd29fe077b3d2676d4437a47f1c00e6b1b0d Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Wed, 27 Sep 2023 05:51:13 +0200 Subject: [PATCH 4/6] wyoming-openwakeword: init at 1.5.1 Wyoming server for the openWakeWord library. --- pkgs/tools/audio/wyoming/openwakeword.nix | 63 +++++++++++++++++++++++ pkgs/top-level/all-packages.nix | 2 + 2 files changed, 65 insertions(+) create mode 100644 pkgs/tools/audio/wyoming/openwakeword.nix diff --git a/pkgs/tools/audio/wyoming/openwakeword.nix b/pkgs/tools/audio/wyoming/openwakeword.nix new file mode 100644 index 000000000000..d8450dac6983 --- /dev/null +++ b/pkgs/tools/audio/wyoming/openwakeword.nix @@ -0,0 +1,63 @@ +{ lib +, python3 +, python3Packages +, fetchFromGitHub +, fetchpatch +}: + +python3.pkgs.buildPythonApplication { + pname = "wyoming-openwakeword"; + version = "1.5.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "rhasspy"; + repo = "rhasspy3"; + rev = "e16d7d374a64f671db48142c7b635b327660ebcf"; + hash = "sha256-SbWsRmR1hfuU3yJbuu+r7M43ugHeNwLgu5S8MqkbCQA="; + }; + + patches = [ + (fetchpatch { + # import tflite entrypoint from tensorflow + url = "https://github.com/rhasspy/rhasspy3/commit/23b1bc9cf1e9aa78453feb11e27d5dafe26de068.patch"; + hash = "sha256-fjLJ+VI4c8ABBWx1IjZ6nS8MGqdry4rgcThKiaAvz+Q="; + }) + (fetchpatch { + # add commandline entrypoint + url = "https://github.com/rhasspy/rhasspy3/commit/7662b82cd85e16817a3c6f4153e855bf57436ac3.patch"; + hash = "sha256-41CLkVDSAJJpZ5irwIf/Z4wHoCuKDrqFBAjKCx7ta50="; + }) + ]; + + postPatch = '' + cd programs/wake/openwakeword-lite/server + ''; + + nativeBuildInputs = with python3Packages; [ + setuptools + wheel + ]; + + propagatedBuildInputs = with python3Packages; [ + tensorflow-bin + webrtc-noise-gain + wyoming + ]; + + passthru.optional-dependencies.webrtc = with python3Packages; [ + webrtc-noise-gain + ]; + + pythonImportsCheck = [ + "wyoming_openwakeword" + ]; + + meta = with lib; { + description = "An open source voice assistant toolkit for many human languages"; + homepage = "https://github.com/rhasspy/rhasspy3/commit/fe44635132079db74d0c76c6b3553b842aa1e318"; + license = licenses.mit; + maintainers = with maintainers; [ hexa ]; + mainProgram = "wyoming-openwakeword"; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index aa17ee1d6921..1b076b7126bf 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -37470,6 +37470,8 @@ with pkgs; wyoming-faster-whisper = callPackage ../tools/audio/wyoming/faster-whisper.nix { }; + wyoming-openwakeword = callPackage ../tools/audio/wyoming/openwakeword.nix { }; + wyoming-piper = callPackage ../tools/audio/wyoming/piper.nix { }; ### GAMES From ed61941b9553a9b7038e8d4cd3deaddc5eaa53da Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Wed, 27 Sep 2023 05:50:37 +0200 Subject: [PATCH 5/6] python311Packages.wyoming: test reverse dependencies in passthru --- pkgs/development/python-modules/wyoming/default.nix | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pkgs/development/python-modules/wyoming/default.nix b/pkgs/development/python-modules/wyoming/default.nix index ccdb4908729d..b7ae51379cdc 100644 --- a/pkgs/development/python-modules/wyoming/default.nix +++ b/pkgs/development/python-modules/wyoming/default.nix @@ -1,6 +1,11 @@ { lib , buildPythonPackage , fetchPypi + +# tests +, wyoming-faster-whisper +, wyoming-openwakeword +, wyoming-piper }: buildPythonPackage rec { @@ -20,6 +25,14 @@ buildPythonPackage rec { # no tests doCheck = false; + passthru.tests = { + inherit + wyoming-faster-whisper + wyoming-openwakeword + wyoming-piper + ; + }; + meta = with lib; { description = "Protocol for Rhasspy Voice Assistant"; homepage = "https://pypi.org/project/wyoming/"; From b571d96667fcb9d667b31e9f79c960a1da337c91 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Fri, 29 Sep 2023 23:07:34 +0200 Subject: [PATCH 6/6] nixos/wyoming/openwakeword: init The wyoming server for providing access to openWakeWord. --- nixos/modules/module-list.nix | 1 + .../services/audio/wyoming/openwakeword.nix | 157 ++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 nixos/modules/services/audio/wyoming/openwakeword.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 66782d046914..ec6f410a48f6 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -346,6 +346,7 @@ ./services/audio/squeezelite.nix ./services/audio/tts.nix ./services/audio/wyoming/faster-whisper.nix + ./services/audio/wyoming/openwakeword.nix ./services/audio/wyoming/piper.nix ./services/audio/ympd.nix ./services/backup/automysqlbackup.nix diff --git a/nixos/modules/services/audio/wyoming/openwakeword.nix b/nixos/modules/services/audio/wyoming/openwakeword.nix new file mode 100644 index 000000000000..e1993407dad1 --- /dev/null +++ b/nixos/modules/services/audio/wyoming/openwakeword.nix @@ -0,0 +1,157 @@ +{ config +, lib +, pkgs +, ... +}: + +let + cfg = config.services.wyoming.openwakeword; + + inherit (lib) + concatMapStringsSep + escapeShellArgs + mkOption + mdDoc + mkEnableOption + mkIf + mkPackageOptionMD + types + ; + + inherit (builtins) + toString + ; + + models = [ + # wyoming_openwakeword/models/*.tflite + "alexa" + "hey_jarvis" + "hey_mycroft" + "hey_rhasspy" + "ok_nabu" + ]; + +in + +{ + meta.buildDocsInSandbox = false; + + options.services.wyoming.openwakeword = with types; { + enable = mkEnableOption (mdDoc "Wyoming openWakeWord server"); + + package = mkPackageOptionMD pkgs "wyoming-openwakeword" { }; + + uri = mkOption { + type = strMatching "^(tcp|unix)://.*$"; + default = "tcp://0.0.0.0:10400"; + example = "tcp://192.0.2.1:5000"; + description = mdDoc '' + URI to bind the wyoming server to. + ''; + }; + + models = mkOption { + type = listOf (enum models); + default = models; + description = mdDoc '' + List of wake word models that should be made available. + ''; + }; + + preloadModels = mkOption { + type = listOf (enum models); + default = [ + "ok_nabu" + ]; + description = mdDoc '' + List of wake word models to preload after startup. + ''; + }; + + threshold = mkOption { + type = float; + default = 0.5; + description = mdDoc '' + Activation threshold (0-1), where higher means fewer activations. + + See trigger level for the relationship between activations and + wake word detections. + ''; + apply = toString; + }; + + triggerLevel = mkOption { + type = int; + default = 1; + description = mdDoc '' + Number of activations before a detection is registered. + + A higher trigger level means fewer detections. + ''; + apply = toString; + }; + + extraArgs = mkOption { + type = listOf str; + default = [ ]; + description = mdDoc '' + Extra arguments to pass to the server commandline. + ''; + apply = escapeShellArgs; + }; + }; + + config = mkIf cfg.enable { + systemd.services."wyoming-openwakeword" = { + description = "Wyoming openWakeWord server"; + after = [ + "network-online.target" + ]; + wantedBy = [ + "multi-user.target" + ]; + serviceConfig = { + DynamicUser = true; + User = "wyoming-openwakeword"; + # https://github.com/home-assistant/addons/blob/master/openwakeword/rootfs/etc/s6-overlay/s6-rc.d/openwakeword/run + ExecStart = '' + ${cfg.package}/bin/wyoming-openwakeword \ + --uri ${cfg.uri} \ + ${concatMapStringsSep " " (model: "--model ${model}") cfg.models} \ + ${concatMapStringsSep " " (model: "--preload-model ${model}") cfg.preloadModels} \ + --threshold ${cfg.threshold} \ + --trigger-level ${cfg.triggerLevel} ${cfg.extraArgs} + ''; + CapabilityBoundingSet = ""; + DeviceAllow = ""; + DevicePolicy = "closed"; + LockPersonality = true; + MemoryDenyWriteExecute = true; + PrivateDevices = true; + PrivateUsers = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectControlGroups = true; + ProtectProc = "invisible"; + ProcSubset = "pid"; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + "AF_UNIX" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RuntimeDirectory = "wyoming-openwakeword"; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + "~@privileged" + ]; + UMask = "0077"; + }; + }; + }; +}