diff --git a/.gitignore b/.gitignore index 97263acd..59cf5ae0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,3 @@ modules/ **/result *.qcow -**/target diff --git a/flakes/de_plasma/de_plasma.nix b/flakes/de_plasma/de_plasma.nix index da13a35a..e001843e 100644 --- a/flakes/de_plasma/de_plasma.nix +++ b/flakes/de_plasma/de_plasma.nix @@ -149,9 +149,6 @@ in kdePackages.plasma-browser-integration # kdePackages.plasma-workspace-wallpapers - # On-screen keyboard (Plasma Wayland) - kdePackages.plasma-keyboard - # Panel applets required for widgets kdePackages.plasma-nm # org.kde.plasma.networkmanagement kdePackages.bluedevil # org.kde.plasma.bluetooth diff --git a/flakes/stt_ime/README.md b/flakes/stt_ime/README.md deleted file mode 100644 index 0dda446f..00000000 --- a/flakes/stt_ime/README.md +++ /dev/null @@ -1,108 +0,0 @@ -# stt_ime - Speech-to-Text Input Method for Fcitx5 - -Local, privacy-preserving speech-to-text that integrates as a native Fcitx5 input method. - -## Components - -- **stt-stream**: Rust CLI that captures audio, runs VAD, and transcribes with Whisper -- **fcitx5-stt**: C++ Fcitx5 addon that spawns stt-stream and commits text to apps - -## Modes - -- **Manual**: Press `Ctrl+Space` or `Ctrl+R` to start/stop recording -- **Oneshot**: Automatically starts on speech, commits on silence, then resets -- **Continuous**: Always listening, commits each utterance automatically - -Press `Ctrl+M` while STT is active to cycle between modes. - -## Keys (when STT input method is active) - -| Key | Action | -|-----|--------| -| `Ctrl+Space` / `Ctrl+R` | Toggle recording (manual mode) | -| `Ctrl+M` | Cycle mode (manual → oneshot → continuous) | -| `Enter` | Accept current preedit text | -| `Escape` | Cancel recording / clear preedit | - -## Usage - -### NixOS Module - -```nix -# In your host's flake.nix inputs: -stt_ime.url = "git+https://git.ros.one/josh/nixos-config?dir=flakes/stt_ime"; - -# In your NixOS config: -{ - imports = [ inputs.stt_ime.nixosModules.default ]; - - ringofstorms.sttIme = { - enable = true; - model = "base.en"; # tiny, base, small, medium, large-v3 (add .en for English-only) - useGpu = false; # set true for CUDA acceleration - }; -} -``` - -### Standalone CLI - -```bash -# Run with default settings (manual mode) -stt-stream - -# Run in continuous mode -stt-stream --mode continuous - -# Use a specific model -stt-stream --model small-en - -# Commands via stdin (manual mode): -echo "start" | stt-stream # begin recording -echo "stop" | stt-stream # stop and transcribe -echo "cancel" | stt-stream # cancel without transcribing -echo "shutdown" | stt-stream # exit -``` - -### Output Format (NDJSON) - -```json -{"type":"ready"} -{"type":"recording_started"} -{"type":"partial","text":"hello worl"} -{"type":"partial","text":"hello world"} -{"type":"final","text":"Hello world."} -{"type":"recording_stopped"} -{"type":"shutdown"} -``` - -## Models - -Models are automatically downloaded from Hugging Face on first run and cached in `~/.cache/stt-stream/models/`. - -| Model | Size | Speed | Quality | -|-------|------|-------|---------| -| tiny.en | ~75MB | Fastest | Basic | -| base.en | ~150MB | Fast | Good (default) | -| small.en | ~500MB | Medium | Better | -| medium.en | ~1.5GB | Slow | Great | -| large-v3 | ~3GB | Slowest | Best (multilingual) | - -## Environment Variables - -- `STT_STREAM_MODEL_PATH`: Path to a specific model file -- `STT_STREAM_MODEL`: Model name (overridden by CLI) -- `STT_STREAM_USE_GPU`: Set to "1" for GPU acceleration - -## Building - -```bash -cd flakes/stt_ime -nix build .#stt-stream # Rust CLI only -nix build .#fcitx5-stt # Fcitx5 addon (includes stt-stream) -nix build # Default: fcitx5-stt -``` - -## Integration with de_plasma - -The addon is automatically added to Fcitx5 when `ringofstorms.sttIme.enable = true`. -It appears as "Speech to Text" (STT) in the input method switcher alongside US and Mozc. diff --git a/flakes/stt_ime/fcitx5-stt/CMakeLists.txt b/flakes/stt_ime/fcitx5-stt/CMakeLists.txt deleted file mode 100644 index 57917248..00000000 --- a/flakes/stt_ime/fcitx5-stt/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(fcitx5-stt VERSION 0.1.0 LANGUAGES CXX) - -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# Find Fcitx5 -find_package(Fcitx5Core REQUIRED) -find_package(Fcitx5Utils REQUIRED) - -# Path to stt-stream binary (set by Nix) -if(NOT DEFINED STT_STREAM_PATH) - set(STT_STREAM_PATH "stt-stream") -endif() - -# Configure header with path -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in - ${CMAKE_CURRENT_BINARY_DIR}/config.h -) - -# Build the addon shared library -add_library(stt MODULE - src/stt.cpp -) - -target_include_directories(stt PRIVATE - ${CMAKE_CURRENT_BINARY_DIR} -) - -target_link_libraries(stt PRIVATE - Fcitx5::Core - Fcitx5::Utils -) - -# Set output name without "lib" prefix -set_target_properties(stt PROPERTIES PREFIX "") - -# Install targets - use standard paths, Nix postInstall will handle fcitx5 paths -install(TARGETS stt DESTINATION lib/fcitx5) -install(FILES data/stt.conf DESTINATION share/fcitx5/addon) -install(FILES data/stt-im.conf DESTINATION share/fcitx5/inputmethod) diff --git a/flakes/stt_ime/fcitx5-stt/data/stt-im.conf b/flakes/stt_ime/fcitx5-stt/data/stt-im.conf deleted file mode 100644 index 8b62855f..00000000 --- a/flakes/stt_ime/fcitx5-stt/data/stt-im.conf +++ /dev/null @@ -1,7 +0,0 @@ -[InputMethod] -Name=Speech to Text -Icon=audio-input-microphone -Label=STT -LangCode= -Addon=stt -Configurable=False diff --git a/flakes/stt_ime/fcitx5-stt/data/stt.conf b/flakes/stt_ime/fcitx5-stt/data/stt.conf deleted file mode 100644 index 28a54774..00000000 --- a/flakes/stt_ime/fcitx5-stt/data/stt.conf +++ /dev/null @@ -1,7 +0,0 @@ -[Addon] -Name=stt -Category=InputMethod -Library=stt -Type=SharedLibrary -OnDemand=True -Configurable=False diff --git a/flakes/stt_ime/fcitx5-stt/src/config.h.in b/flakes/stt_ime/fcitx5-stt/src/config.h.in deleted file mode 100644 index 3626c88f..00000000 --- a/flakes/stt_ime/fcitx5-stt/src/config.h.in +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -// Path to stt-stream binary -#define STT_STREAM_PATH "@STT_STREAM_PATH@" diff --git a/flakes/stt_ime/fcitx5-stt/src/stt.cpp b/flakes/stt_ime/fcitx5-stt/src/stt.cpp deleted file mode 100644 index eb738860..00000000 --- a/flakes/stt_ime/fcitx5-stt/src/stt.cpp +++ /dev/null @@ -1,533 +0,0 @@ -/* - * fcitx5-stt: Speech-to-Text Input Method Engine for Fcitx5 - * - * This is a thin shim that spawns the stt-stream Rust binary and - * bridges its JSON events to Fcitx5's input method API. - * - * Modes: - * - Oneshot: Record until silence, commit, reset - * - Continuous: Always listen, commit on silence - * - Manual: Start/stop via hotkey - * - * UX: - * - Partial text shown as preedit (underlined) - * - Final text committed on stop/silence - * - Escape cancels without committing - * - Enter accepts current preedit - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" - -namespace { - -FCITX_DEFINE_LOG_CATEGORY(stt_log, "stt"); -#define STT_DEBUG() FCITX_LOGC(stt_log, Debug) -#define STT_INFO() FCITX_LOGC(stt_log, Info) -#define STT_WARN() FCITX_LOGC(stt_log, Warn) -#define STT_ERROR() FCITX_LOGC(stt_log, Error) - -// Operating modes -enum class SttMode { - Oneshot, - Continuous, - Manual -}; - -// Simple JSON parsing (we only need a few fields) -struct JsonEvent { - std::string type; - std::string text; - std::string message; - - static JsonEvent parse(const std::string& line) { - JsonEvent ev; - // Very basic JSON parsing - find "type" and "text" fields - auto findValue = [&line](const std::string& key) -> std::string { - std::string search = "\"" + key + "\":\""; - auto pos = line.find(search); - if (pos == std::string::npos) return ""; - pos += search.length(); - auto end = line.find("\"", pos); - if (end == std::string::npos) return ""; - return line.substr(pos, end - pos); - }; - - ev.type = findValue("type"); - ev.text = findValue("text"); - ev.message = findValue("message"); - return ev; - } -}; - -} // anonymous namespace - -class SttEngine; - -class SttState : public fcitx::InputContextProperty { -public: - SttState(SttEngine* engine, fcitx::InputContext* ic) - : engine_(engine), ic_(ic) {} - - void setPreedit(const std::string& text); - void commit(const std::string& text); - void clear(); - - bool isRecording() const { return recording_; } - void setRecording(bool r) { recording_ = r; } - - const std::string& preeditText() const { return preedit_; } - -private: - SttEngine* engine_; - fcitx::InputContext* ic_; - std::string preedit_; - bool recording_ = false; -}; - -class SttEngine : public fcitx::InputMethodEngineV2 { -public: - SttEngine(fcitx::Instance* instance); - ~SttEngine() override; - - // InputMethodEngine interface - void activate(const fcitx::InputMethodEntry& entry, - fcitx::InputContextEvent& event) override; - void deactivate(const fcitx::InputMethodEntry& entry, - fcitx::InputContextEvent& event) override; - void keyEvent(const fcitx::InputMethodEntry& entry, - fcitx::KeyEvent& keyEvent) override; - void reset(const fcitx::InputMethodEntry& entry, - fcitx::InputContextEvent& event) override; - - // List input methods this engine provides - std::vector listInputMethods() override { - std::vector result; - result.emplace_back( - "stt", // unique name - _("Speech to Text"), // display name - "*", // language (any) - "stt" // addon name - ); - return result; - } - - fcitx::Instance* instance() { return instance_; } - - // Process management - void startProcess(); - void stopProcess(); - void sendCommand(const std::string& cmd); - - // Mode - SttMode mode() const { return mode_; } - void setMode(SttMode m); - void cycleMode(); - -private: - void onProcessOutput(); - void handleEvent(const JsonEvent& ev); - - fcitx::Instance* instance_; - fcitx::FactoryFor factory_; - - // Process state - pid_t childPid_ = -1; - int stdinFd_ = -1; - int stdoutFd_ = -1; - std::unique_ptr ioEvent_; - std::string readBuffer_; - - // Mode - SttMode mode_ = SttMode::Manual; - - // Current state - bool ready_ = false; - fcitx::InputContext* activeIc_ = nullptr; -}; - -// SttState implementation -void SttState::setPreedit(const std::string& text) { - preedit_ = text; - if (ic_->hasFocus()) { - fcitx::Text preeditText; - preeditText.append(text, fcitx::TextFormatFlag::Underline); - preeditText.setCursor(text.length()); - ic_->inputPanel().setClientPreedit(preeditText); - ic_->updatePreedit(); - } -} - -void SttState::commit(const std::string& text) { - if (!text.empty() && ic_->hasFocus()) { - ic_->commitString(text); - } - clear(); -} - -void SttState::clear() { - preedit_.clear(); - if (ic_->hasFocus()) { - ic_->inputPanel().reset(); - ic_->updatePreedit(); - ic_->updateUserInterface(fcitx::UserInterfaceComponent::InputPanel); - } -} - -// SttEngine implementation -SttEngine::SttEngine(fcitx::Instance* instance) - : instance_(instance), - factory_([this](fcitx::InputContext& ic) { - return new SttState(this, &ic); - }) { - instance_->inputContextManager().registerProperty("sttState", &factory_); - STT_INFO() << "SttEngine initialized"; -} - -SttEngine::~SttEngine() { - stopProcess(); -} - -void SttEngine::activate(const fcitx::InputMethodEntry& entry, - fcitx::InputContextEvent& event) { - FCITX_UNUSED(entry); - auto* ic = event.inputContext(); - activeIc_ = ic; - - STT_INFO() << "STT activated"; - - // Start the backend process if not running - if (childPid_ < 0) { - startProcess(); - } - - // In continuous mode, start recording automatically - if (mode_ == SttMode::Continuous && ready_) { - sendCommand("start"); - auto* state = ic->propertyFor(&factory_); - state->setRecording(true); - } -} - -void SttEngine::deactivate(const fcitx::InputMethodEntry& entry, - fcitx::InputContextEvent& event) { - FCITX_UNUSED(entry); - auto* ic = event.inputContext(); - auto* state = ic->propertyFor(&factory_); - - // Stop recording if active - if (state->isRecording()) { - sendCommand("cancel"); - state->setRecording(false); - } - state->clear(); - - activeIc_ = nullptr; - STT_INFO() << "STT deactivated"; -} - -void SttEngine::keyEvent(const fcitx::InputMethodEntry& entry, - fcitx::KeyEvent& keyEvent) { - FCITX_UNUSED(entry); - auto* ic = keyEvent.inputContext(); - auto* state = ic->propertyFor(&factory_); - - // Handle special keys - if (keyEvent.isRelease()) { - return; - } - - auto key = keyEvent.key(); - - // Escape: cancel recording/preedit - if (key.check(FcitxKey_Escape)) { - if (state->isRecording() || !state->preeditText().empty()) { - sendCommand("cancel"); - state->setRecording(false); - state->clear(); - keyEvent.filterAndAccept(); - return; - } - } - - // Enter/Return: accept preedit - if (key.check(FcitxKey_Return) || key.check(FcitxKey_KP_Enter)) { - if (!state->preeditText().empty()) { - state->commit(state->preeditText()); - sendCommand("cancel"); - state->setRecording(false); - keyEvent.filterAndAccept(); - return; - } - } - - // Space or Ctrl+R: toggle recording (in manual mode) - if (mode_ == SttMode::Manual) { - if (key.check(FcitxKey_space, fcitx::KeyState::Ctrl) || - key.check(FcitxKey_r, fcitx::KeyState::Ctrl)) { - if (state->isRecording()) { - sendCommand("stop"); - state->setRecording(false); - } else { - state->clear(); - sendCommand("start"); - state->setRecording(true); - } - keyEvent.filterAndAccept(); - return; - } - } - - // Ctrl+M: cycle mode - if (key.check(FcitxKey_m, fcitx::KeyState::Ctrl)) { - cycleMode(); - keyEvent.filterAndAccept(); - return; - } - - // In recording state, absorb most keys - if (state->isRecording()) { - keyEvent.filterAndAccept(); - return; - } -} - -void SttEngine::reset(const fcitx::InputMethodEntry& entry, - fcitx::InputContextEvent& event) { - FCITX_UNUSED(entry); - auto* ic = event.inputContext(); - auto* state = ic->propertyFor(&factory_); - state->clear(); -} - -void SttEngine::startProcess() { - if (childPid_ > 0) { - return; // Already running - } - - int stdinPipe[2]; - int stdoutPipe[2]; - - if (pipe(stdinPipe) < 0 || pipe(stdoutPipe) < 0) { - STT_ERROR() << "Failed to create pipes"; - return; - } - - pid_t pid = fork(); - if (pid < 0) { - STT_ERROR() << "Failed to fork"; - close(stdinPipe[0]); - close(stdinPipe[1]); - close(stdoutPipe[0]); - close(stdoutPipe[1]); - return; - } - - if (pid == 0) { - // Child process - close(stdinPipe[1]); - close(stdoutPipe[0]); - - dup2(stdinPipe[0], STDIN_FILENO); - dup2(stdoutPipe[1], STDOUT_FILENO); - - close(stdinPipe[0]); - close(stdoutPipe[1]); - - // Determine mode string - const char* modeStr = "manual"; - switch (mode_) { - case SttMode::Oneshot: modeStr = "oneshot"; break; - case SttMode::Continuous: modeStr = "continuous"; break; - case SttMode::Manual: modeStr = "manual"; break; - } - - execlp(STT_STREAM_PATH, "stt-stream", "--mode", modeStr, nullptr); - _exit(127); - } - - // Parent process - close(stdinPipe[0]); - close(stdoutPipe[1]); - - childPid_ = pid; - stdinFd_ = stdinPipe[1]; - stdoutFd_ = stdoutPipe[0]; - - // Set stdout non-blocking - int flags = fcntl(stdoutFd_, F_GETFL, 0); - fcntl(stdoutFd_, F_SETFL, flags | O_NONBLOCK); - - // Watch stdout for events - ioEvent_ = instance_->eventLoop().addIOEvent( - stdoutFd_, - fcitx::IOEventFlag::In, - [this](fcitx::EventSourceIO*, int, fcitx::IOEventFlags) { - onProcessOutput(); - return true; - } - ); - - STT_INFO() << "Started stt-stream process (pid=" << childPid_ << ")"; -} - -void SttEngine::stopProcess() { - if (childPid_ < 0) { - return; - } - - ioEvent_.reset(); - - sendCommand("shutdown"); - close(stdinFd_); - close(stdoutFd_); - - // Wait for child to exit - int status; - waitpid(childPid_, &status, 0); - - stdinFd_ = -1; - stdoutFd_ = -1; - childPid_ = -1; - ready_ = false; - - STT_INFO() << "Stopped stt-stream process"; -} - -void SttEngine::sendCommand(const std::string& cmd) { - if (stdinFd_ < 0) { - return; - } - - std::string line = cmd + "\n"; - write(stdinFd_, line.c_str(), line.length()); -} - -void SttEngine::onProcessOutput() { - char buf[4096]; - ssize_t n; - - while ((n = read(stdoutFd_, buf, sizeof(buf) - 1)) > 0) { - buf[n] = '\0'; - readBuffer_ += buf; - - // Process complete lines - size_t pos; - while ((pos = readBuffer_.find('\n')) != std::string::npos) { - std::string line = readBuffer_.substr(0, pos); - readBuffer_ = readBuffer_.substr(pos + 1); - - if (!line.empty()) { - auto ev = JsonEvent::parse(line); - handleEvent(ev); - } - } - } -} - -void SttEngine::handleEvent(const JsonEvent& ev) { - STT_DEBUG() << "Event: type=" << ev.type << " text=" << ev.text; - - if (ev.type == "ready") { - ready_ = true; - STT_INFO() << "stt-stream ready"; - } else if (ev.type == "recording_started") { - // Update UI to show recording state - if (activeIc_) { - auto* state = activeIc_->propertyFor(&factory_); - state->setRecording(true); - } - } else if (ev.type == "recording_stopped") { - if (activeIc_) { - auto* state = activeIc_->propertyFor(&factory_); - state->setRecording(false); - } - } else if (ev.type == "partial") { - if (activeIc_) { - auto* state = activeIc_->propertyFor(&factory_); - state->setPreedit(ev.text); - } - } else if (ev.type == "final") { - if (activeIc_) { - auto* state = activeIc_->propertyFor(&factory_); - state->commit(ev.text); - state->setRecording(false); - - // In oneshot mode, we're done - // In continuous mode, keep listening - if (mode_ == SttMode::Continuous && ready_) { - sendCommand("start"); - state->setRecording(true); - } - } - } else if (ev.type == "error") { - STT_ERROR() << "stt-stream error: " << ev.message; - } else if (ev.type == "shutdown") { - ready_ = false; - } -} - -void SttEngine::setMode(SttMode m) { - if (mode_ == m) return; - - mode_ = m; - - // Notify the backend - const char* modeStr = "manual"; - switch (m) { - case SttMode::Oneshot: modeStr = "oneshot"; break; - case SttMode::Continuous: modeStr = "continuous"; break; - case SttMode::Manual: modeStr = "manual"; break; - } - - std::string cmd = "{\"cmd\":\"set_mode\",\"mode\":\""; - cmd += modeStr; - cmd += "\"}"; - sendCommand(cmd); - - STT_INFO() << "Mode changed to: " << modeStr; -} - -void SttEngine::cycleMode() { - switch (mode_) { - case SttMode::Manual: - setMode(SttMode::Oneshot); - break; - case SttMode::Oneshot: - setMode(SttMode::Continuous); - break; - case SttMode::Continuous: - setMode(SttMode::Manual); - break; - } -} - -// Addon factory -class SttEngineFactory : public fcitx::AddonFactory { -public: - fcitx::AddonInstance* create(fcitx::AddonManager* manager) override { - return new SttEngine(manager->instance()); - } -}; - -FCITX_ADDON_FACTORY(SttEngineFactory); diff --git a/flakes/stt_ime/flake.lock b/flakes/stt_ime/flake.lock deleted file mode 100644 index c22bd6f2..00000000 --- a/flakes/stt_ime/flake.lock +++ /dev/null @@ -1,77 +0,0 @@ -{ - "nodes": { - "crane": { - "locked": { - "lastModified": 1768319649, - "narHash": "sha256-VFkNyxHxkqGp8gf8kfFMW1j6XeBy609kv6TE9uF/0Js=", - "owner": "ipetkov", - "repo": "crane", - "rev": "4b6527687cfd20da3c2ef8287e01b74c2d6c705b", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1768127708, - "narHash": "sha256-1Sm77VfZh3mU0F5OqKABNLWxOuDeHIlcFjsXeeiPazs=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "ffbc9f8cbaacfb331b6017d5a5abb21a492c9a38", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "crane": "crane", - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flakes/stt_ime/flake.nix b/flakes/stt_ime/flake.nix deleted file mode 100644 index 0e6ae14d..00000000 --- a/flakes/stt_ime/flake.nix +++ /dev/null @@ -1,166 +0,0 @@ -{ - description = "Local speech-to-text input method for Fcitx5"; - - inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; - crane.url = "github:ipetkov/crane"; - flake-utils.url = "github:numtide/flake-utils"; - }; - - outputs = - { - self, - nixpkgs, - crane, - flake-utils, - ... - }: - let - # Systems we support - supportedSystems = [ - "x86_64-linux" - "aarch64-linux" - ]; - in - flake-utils.lib.eachSystem supportedSystems ( - system: - let - pkgs = nixpkgs.legacyPackages.${system}; - craneLib = crane.mkLib pkgs; - - # Rust STT streaming CLI - stt-stream = craneLib.buildPackage { - pname = "stt-stream"; - version = "0.1.0"; - src = craneLib.cleanCargoSource ./stt-stream; - - nativeBuildInputs = with pkgs; [ - pkg-config - cmake # for whisper-rs - clang - llvmPackages.libclang - ]; - - buildInputs = with pkgs; [ - alsa-lib - openssl - # whisper.cpp dependencies - openblas - ]; - - # For bindgen to find libclang - LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib"; - - # Enable CUDA if available (user can override) - WHISPER_CUBLAS = "OFF"; - }; - - # Fcitx5 C++ shim addon - fcitx5-stt = pkgs.stdenv.mkDerivation { - pname = "fcitx5-stt"; - version = "0.1.0"; - src = ./fcitx5-stt; - - nativeBuildInputs = with pkgs; [ - cmake - extra-cmake-modules - pkg-config - ]; - - buildInputs = with pkgs; [ - fcitx5 - ]; - - cmakeFlags = [ - "-DSTT_STREAM_PATH=${stt-stream}/bin/stt-stream" - ]; - - # Install to fcitx5 addon paths - postInstall = '' - mkdir -p $out/share/fcitx5/addon - mkdir -p $out/share/fcitx5/inputmethod - mkdir -p $out/lib/fcitx5 - ''; - }; - in - { - packages = { - inherit stt-stream fcitx5-stt; - default = fcitx5-stt; - }; - - # Expose as runnable apps - apps = { - stt-stream = { - type = "app"; - program = "${stt-stream}/bin/stt-stream"; - }; - default = { - type = "app"; - program = "${stt-stream}/bin/stt-stream"; - }; - }; - - devShells.default = pkgs.mkShell { - inputsFrom = [ stt-stream ]; - packages = with pkgs; [ - rust-analyzer - rustfmt - clippy - fcitx5 - ]; - }; - } - ) - // { - # NixOS module for integration - nixosModules.default = - { - config, - lib, - pkgs, - ... - }: - let - cfg = config.ringofstorms.sttIme; - sttPkgs = self.packages.${pkgs.stdenv.hostPlatform.system}; - in - { - options.ringofstorms.sttIme = { - enable = lib.mkEnableOption "Speech-to-text input method for Fcitx5"; - - model = lib.mkOption { - type = lib.types.str; - default = "base.en"; - description = "Whisper model to use (tiny, base, small, medium, large)"; - }; - - useGpu = lib.mkOption { - type = lib.types.bool; - default = false; - description = "Whether to use GPU acceleration (CUDA)"; - }; - }; - - config = lib.mkIf cfg.enable { - # Ensure fcitx5 addon is available - i18n.inputMethod.fcitx5.addons = [ sttPkgs.fcitx5-stt ]; - - # Add STT to the Fcitx5 input method group - # This assumes de_plasma sets up Groups/0 with keyboard-us (0) and mozc (1) - i18n.inputMethod.fcitx5.settings.inputMethod = { - "Groups/0/Items/2".Name = "stt"; - }; - - # Make stt-stream available system-wide - environment.systemPackages = [ sttPkgs.stt-stream ]; - - # Set default model via environment - environment.sessionVariables = { - STT_STREAM_MODEL = cfg.model; - STT_STREAM_USE_GPU = if cfg.useGpu then "1" else "0"; - }; - }; - }; - }; -} diff --git a/flakes/stt_ime/stt-stream/Cargo.lock b/flakes/stt_ime/stt-stream/Cargo.lock deleted file mode 100644 index b25c4923..00000000 --- a/flakes/stt_ime/stt-stream/Cargo.lock +++ /dev/null @@ -1,2487 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "aho-corasick" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" -dependencies = [ - "memchr", -] - -[[package]] -name = "alsa" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43" -dependencies = [ - "alsa-sys", - "bitflags 2.10.0", - "cfg-if", - "libc", -] - -[[package]] -name = "alsa-sys" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527" -dependencies = [ - "libc", - "pkg-config", -] - -[[package]] -name = "anstream" -version = "0.6.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" - -[[package]] -name = "anstyle-parse" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" -dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys 0.61.2", -] - -[[package]] -name = "anyhow" -version = "1.0.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bindgen" -version = "0.69.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" -dependencies = [ - "bitflags 2.10.0", - "cexpr", - "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn", - "which", -] - -[[package]] -name = "bindgen" -version = "0.72.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" -dependencies = [ - "bitflags 2.10.0", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "proc-macro2", - "quote", - "regex", - "rustc-hash 2.1.1", - "shlex", - "syn", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" - -[[package]] -name = "bumpalo" -version = "3.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" - -[[package]] -name = "bytes" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" - -[[package]] -name = "cc" -version = "1.2.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3" -dependencies = [ - "find-msvc-tools", - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "clap" -version = "4.5.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" - -[[package]] -name = "cmake" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" -dependencies = [ - "cc", -] - -[[package]] -name = "colorchoice" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" - -[[package]] -name = "combine" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "memchr", -] - -[[package]] -name = "console" -version = "0.15.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" -dependencies = [ - "encode_unicode", - "libc", - "once_cell", - "unicode-width", - "windows-sys 0.59.0", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "coreaudio-rs" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321077172d79c662f64f5071a03120748d5bb652f5231570141be24cfcd2bace" -dependencies = [ - "bitflags 1.3.2", - "core-foundation-sys", - "coreaudio-sys", -] - -[[package]] -name = "coreaudio-sys" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceec7a6067e62d6f931a2baf6f3a751f4a892595bcec1461a3c94ef9949864b6" -dependencies = [ - "bindgen 0.72.1", -] - -[[package]] -name = "cpal" -version = "0.15.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "873dab07c8f743075e57f524c583985fbaf745602acbe916a01539364369a779" -dependencies = [ - "alsa", - "core-foundation-sys", - "coreaudio-rs", - "dasp_sample", - "jni", - "js-sys", - "libc", - "mach2", - "ndk", - "ndk-context", - "oboe", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "windows", -] - -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "dasp_sample" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" - -[[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "encode_unicode" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "find-msvc-tools" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41" - -[[package]] -name = "flate2" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - -[[package]] -name = "getrandom" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasip2", -] - -[[package]] -name = "glob" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - -[[package]] -name = "hashbrown" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hf-hub" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b780635574b3d92f036890d8373433d6f9fc7abb320ee42a5c25897fc8ed732" -dependencies = [ - "dirs", - "indicatif", - "log", - "native-tls", - "rand", - "serde", - "serde_json", - "thiserror", - "ureq", -] - -[[package]] -name = "home" -version = "0.5.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "icu_collections" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" - -[[package]] -name = "icu_properties" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" - -[[package]] -name = "icu_provider" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "2.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "indicatif" -version = "0.17.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" -dependencies = [ - "console", - "number_prefix", - "portable-atomic", - "unicode-width", - "web-time", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" - -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if", - "combine", - "jni-sys", - "log", - "thiserror", - "walkdir", - "windows-sys 0.45.0", -] - -[[package]] -name = "jni-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" - -[[package]] -name = "jobserver" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" -dependencies = [ - "getrandom 0.3.4", - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.180" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" - -[[package]] -name = "libloading" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link", -] - -[[package]] -name = "libredox" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" -dependencies = [ - "bitflags 2.10.0", - "libc", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" - -[[package]] -name = "litemap" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" - -[[package]] -name = "mach2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" -dependencies = [ - "libc", -] - -[[package]] -name = "matchers" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "memchr" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - -[[package]] -name = "mio" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", -] - -[[package]] -name = "native-tls" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "ndk" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" -dependencies = [ - "bitflags 2.10.0", - "jni-sys", - "log", - "ndk-sys", - "num_enum", - "thiserror", -] - -[[package]] -name = "ndk-context" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" - -[[package]] -name = "ndk-sys" -version = "0.5.0+25.2.9519653" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" -dependencies = [ - "jni-sys", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nu-ansi-term" -version = "0.50.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "num-complex" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_enum" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" -dependencies = [ - "num_enum_derive", - "rustversion", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "number_prefix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" - -[[package]] -name = "oboe" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8b61bebd49e5d43f5f8cc7ee2891c16e0f41ec7954d36bcb6c14c5e0de867fb" -dependencies = [ - "jni", - "ndk", - "ndk-context", - "num-derive", - "num-traits", - "oboe-sys", -] - -[[package]] -name = "oboe-sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8bb09a4a2b1d668170cfe0a7d5bc103f8999fb316c98099b6a9939c9f2e79d" -dependencies = [ - "cc", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "once_cell_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" - -[[package]] -name = "openssl" -version = "0.10.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" -dependencies = [ - "bitflags 2.10.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-probe" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" - -[[package]] -name = "openssl-sys" -version = "0.9.111" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "portable-atomic" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" - -[[package]] -name = "potential_utf" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" -dependencies = [ - "zerovec", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - -[[package]] -name = "primal-check" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0d895b311e3af9902528fbb8f928688abbd95872819320517cc24ca6b2bd08" -dependencies = [ - "num-integer", -] - -[[package]] -name = "proc-macro-crate" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro2" -version = "1.0.105" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.17", -] - -[[package]] -name = "realfft" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f821338fddb99d089116342c46e9f1fbf3828dba077674613e734e01d6ea8677" -dependencies = [ - "rustfft", -] - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags 2.10.0", -] - -[[package]] -name = "redox_users" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" -dependencies = [ - "getrandom 0.2.17", - "libredox", - "thiserror", -] - -[[package]] -name = "regex" -version = "1.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.17", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rubato" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5d18b486e7d29a408ef3f825bc1327d8f87af091c987ca2f5b734625940e234" -dependencies = [ - "num-complex", - "num-integer", - "num-traits", - "realfft", -] - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - -[[package]] -name = "rustfft" -version = "6.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21db5f9893e91f41798c88680037dba611ca6674703c1a18601b01a72c8adb89" -dependencies = [ - "num-complex", - "num-integer", - "num-traits", - "primal-check", - "strength_reduce", - "transpose", -] - -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.10.0", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustix" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" -dependencies = [ - "bitflags 2.10.0", - "errno", - "libc", - "linux-raw-sys 0.11.0", - "windows-sys 0.61.2", -] - -[[package]] -name = "rustls" -version = "0.23.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" -dependencies = [ - "log", - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-pki-types" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" -dependencies = [ - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.10.0", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.149" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" -dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" -dependencies = [ - "errno", - "libc", -] - -[[package]] -name = "simd-adler32" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "socket2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" -dependencies = [ - "libc", - "windows-sys 0.60.2", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "strength_reduce" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "stt-stream" -version = "0.1.0" -dependencies = [ - "anyhow", - "clap", - "cpal", - "hf-hub", - "rubato", - "serde", - "serde_json", - "thiserror", - "tokio", - "tracing", - "tracing-subscriber", - "whisper-rs", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "2.0.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tempfile" -version = "3.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" -dependencies = [ - "fastrand", - "getrandom 0.3.4", - "once_cell", - "rustix 1.1.3", - "windows-sys 0.61.2", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thread_local" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "tinystr" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tokio" -version = "1.49.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" -dependencies = [ - "bytes", - "libc", - "mio", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.61.2", -] - -[[package]] -name = "tokio-macros" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", -] - -[[package]] -name = "toml_edit" -version = "0.23.10+spec-1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" -dependencies = [ - "indexmap", - "toml_datetime", - "toml_parser", - "winnow", -] - -[[package]] -name = "toml_parser" -version = "1.0.6+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" -dependencies = [ - "winnow", -] - -[[package]] -name = "tracing" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex-automata", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "transpose" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" -dependencies = [ - "num-integer", - "strength_reduce", -] - -[[package]] -name = "unicode-ident" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" - -[[package]] -name = "unicode-width" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "ureq" -version = "2.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" -dependencies = [ - "base64", - "flate2", - "log", - "native-tls", - "once_cell", - "rustls", - "rustls-pki-types", - "serde", - "serde_json", - "url", - "webpki-roots 0.26.11", -] - -[[package]] -name = "url" -version = "2.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "valuable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasip2" -version = "1.0.1+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" -dependencies = [ - "cfg-if", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "web-sys" -version = "0.3.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki-roots" -version = "0.26.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" -dependencies = [ - "webpki-roots 1.0.5", -] - -[[package]] -name = "webpki-roots" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix 0.38.44", -] - -[[package]] -name = "whisper-rs" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c597ac8a9d5c4719fee232abc871da184ea50a4fea38d2d00348fd95072b2b0" -dependencies = [ - "whisper-rs-sys", -] - -[[package]] -name = "whisper-rs-sys" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22f00ed0995463eecc34ef89905845f6bf6fd37ea70789fed180520050da8f8" -dependencies = [ - "bindgen 0.69.5", - "cfg-if", - "cmake", - "fs_extra", -] - -[[package]] -name = "winapi-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "windows" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" -dependencies = [ - "windows-core", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" -dependencies = [ - "windows-result", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-result" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "winnow" -version = "0.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" -dependencies = [ - "memchr", -] - -[[package]] -name = "wit-bindgen" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" - -[[package]] -name = "writeable" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" - -[[package]] -name = "yoke" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.8.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" - -[[package]] -name = "zerotrie" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zmij" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd8f3f50b848df28f887acb68e41201b5aea6bc8a8dacc00fb40635ff9a72fea" diff --git a/flakes/stt_ime/stt-stream/Cargo.toml b/flakes/stt_ime/stt-stream/Cargo.toml deleted file mode 100644 index cbd7c8de..00000000 --- a/flakes/stt_ime/stt-stream/Cargo.toml +++ /dev/null @@ -1,50 +0,0 @@ -[package] -name = "stt-stream" -version = "0.1.0" -edition = "2021" -description = "Local speech-to-text streaming CLI for Fcitx5 integration" -license = "MIT" - -[dependencies] -# Audio capture -cpal = "0.15" -# Resampling (48k -> 16k) -rubato = "0.15" -# Whisper inference -whisper-rs = "0.12" -# Voice activity detection -# Using silero via ONNX (reserved for future use) -# ort = { version = "2.0.0-rc.9", default-features = false, features = ["load-dynamic"] } -# ndarray = "0.16" - -# Async runtime -tokio = { version = "1", features = ["full"] } - -# CLI -clap = { version = "4", features = ["derive"] } - -# Serialization for IPC protocol -serde = { version = "1", features = ["derive"] } -serde_json = "1" - -# Error handling -anyhow = "1" -thiserror = "1" - -# Logging -tracing = "0.1" -tracing-subscriber = { version = "0.3", features = ["env-filter"] } - -# Ring buffer for audio (reserved for future use) -# ringbuf = "0.4" - -# For downloading models -hf-hub = "0.3" - -[features] -default = [] -cuda = ["whisper-rs/cuda"] - -[profile.release] -lto = true -codegen-units = 1 diff --git a/flakes/stt_ime/stt-stream/src/main.rs b/flakes/stt_ime/stt-stream/src/main.rs deleted file mode 100644 index e0f92082..00000000 --- a/flakes/stt_ime/stt-stream/src/main.rs +++ /dev/null @@ -1,599 +0,0 @@ -//! stt-stream: Local speech-to-text streaming CLI -//! -//! Captures audio from microphone, performs VAD, transcribes with Whisper, -//! and outputs JSON events to stdout for Fcitx5 integration. - -use anyhow::{Context, Result}; -use clap::{Parser, ValueEnum}; -use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; -use rubato::{FftFixedInOut, Resampler}; -use serde::{Deserialize, Serialize}; -use std::io::{BufRead, Write}; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, Mutex}; -use tokio::sync::mpsc; -use tracing::{error, info, warn}; -use whisper_rs::{FullParams, SamplingStrategy, WhisperContext, WhisperContextParameters}; - -/// Operating mode for the STT engine -#[derive(Debug, Clone, Copy, ValueEnum, PartialEq, Eq)] -pub enum Mode { - /// Record until silence, transcribe, then reset (one-shot) - Oneshot, - /// Always listen, emit text when speech detected (continuous) - Continuous, - /// Manual start/stop via stdin commands - Manual, -} - -/// Whisper model size -#[derive(Debug, Clone, Copy, ValueEnum)] -pub enum ModelSize { - Tiny, - TinyEn, - Base, - BaseEn, - Small, - SmallEn, - Medium, - MediumEn, - LargeV3, -} - -impl ModelSize { - fn model_name(&self) -> &'static str { - match self { - ModelSize::Tiny => "tiny", - ModelSize::TinyEn => "tiny.en", - ModelSize::Base => "base", - ModelSize::BaseEn => "base.en", - ModelSize::Small => "small", - ModelSize::SmallEn => "small.en", - ModelSize::Medium => "medium", - ModelSize::MediumEn => "medium.en", - ModelSize::LargeV3 => "large-v3", - } - } - - fn hf_repo(&self) -> &'static str { - "ggerganov/whisper.cpp" - } - - fn hf_filename(&self) -> String { - format!("ggml-{}.bin", self.model_name()) - } -} - -#[derive(Parser, Debug)] -#[command(name = "stt-stream")] -#[command(about = "Local speech-to-text streaming for Fcitx5")] -struct Args { - /// Operating mode - #[arg(short, long, value_enum, default_value = "manual")] - mode: Mode, - - /// Whisper model size - #[arg(short = 'M', long, value_enum, default_value = "base-en")] - model: ModelSize, - - /// Path to whisper model file (overrides --model) - #[arg(long)] - model_path: Option, - - /// VAD threshold (0.0-1.0) - #[arg(long, default_value = "0.5")] - vad_threshold: f32, - - /// Silence duration (ms) to end utterance - #[arg(long, default_value = "800")] - silence_ms: u64, - - /// Emit partial transcripts while speaking - #[arg(long, default_value = "true")] - partials: bool, - - /// Partial transcript interval (ms) - #[arg(long, default_value = "500")] - partial_interval_ms: u64, - - /// Language code (e.g., "en", "ja", "auto") - #[arg(short, long, default_value = "en")] - language: String, - - /// Use GPU acceleration - #[arg(long)] - gpu: bool, -} - -/// Events emitted to stdout as NDJSON -#[derive(Debug, Serialize)] -#[serde(tag = "type", rename_all = "snake_case")] -pub enum SttEvent { - /// STT engine is ready - Ready, - /// Recording started - RecordingStarted, - /// Recording stopped - RecordingStopped, - /// Partial (unstable) transcript - Partial { text: String }, - /// Final transcript - Final { text: String }, - /// Error occurred - Error { message: String }, - /// Engine shutting down - Shutdown, -} - -/// Commands received from stdin as NDJSON -#[derive(Debug, Deserialize)] -#[serde(tag = "cmd", rename_all = "snake_case")] -pub enum SttCommand { - /// Start recording - Start, - /// Stop recording and transcribe - Stop, - /// Cancel current recording without transcribing - Cancel, - /// Shutdown the engine - Shutdown, - /// Switch mode - SetMode { mode: String }, -} - -fn emit_event(event: &SttEvent) { - if let Ok(json) = serde_json::to_string(event) { - let mut stdout = std::io::stdout().lock(); - let _ = writeln!(stdout, "{}", json); - let _ = stdout.flush(); - } -} - -/// Simple energy-based VAD (placeholder for Silero VAD) -/// Returns true if the audio chunk likely contains speech -fn simple_vad(samples: &[f32], threshold: f32) -> bool { - if samples.is_empty() { - return false; - } - let energy: f32 = samples.iter().map(|s| s * s).sum::() / samples.len() as f32; - let db = 10.0 * energy.max(1e-10).log10(); - // Typical speech is around -20 to -10 dB, silence is < -40 dB - // Map threshold 0-1 to dB range -50 to -20 - let threshold_db = -50.0 + (threshold * 30.0); - db > threshold_db -} - -/// Download or locate the Whisper model -fn get_model_path(args: &Args) -> Result { - if let Some(ref path) = args.model_path { - return Ok(path.clone()); - } - - // Check environment variable - if let Ok(path) = std::env::var("STT_STREAM_MODEL_PATH") { - if std::path::Path::new(&path).exists() { - return Ok(path); - } - } - - // Check XDG cache - let cache_dir = dirs::cache_dir() - .unwrap_or_else(|| std::path::PathBuf::from(".")) - .join("stt-stream") - .join("models"); - - let model_file = cache_dir.join(args.model.hf_filename()); - if model_file.exists() { - return Ok(model_file.to_string_lossy().to_string()); - } - - // Download from Hugging Face - info!("Downloading model {} from Hugging Face...", args.model.model_name()); - std::fs::create_dir_all(&cache_dir)?; - - let api = hf_hub::api::sync::Api::new()?; - let repo = api.model(args.model.hf_repo().to_string()); - let path = repo.get(&args.model.hf_filename())?; - - Ok(path.to_string_lossy().to_string()) -} - -/// Audio processing state -struct AudioState { - /// Audio samples buffer (16kHz mono) - buffer: Vec, - /// Whether we're currently recording - is_recording: bool, - /// Whether speech was detected in current segment - speech_detected: bool, - /// Samples since last speech - silence_samples: usize, - /// Last partial emission time - last_partial: std::time::Instant, -} - -impl AudioState { - fn new() -> Self { - Self { - buffer: Vec::with_capacity(16000 * 30), // 30 seconds max - is_recording: false, - speech_detected: false, - silence_samples: 0, - last_partial: std::time::Instant::now(), - } - } - - fn clear(&mut self) { - self.buffer.clear(); - self.speech_detected = false; - self.silence_samples = 0; - } -} - -#[tokio::main] -async fn main() -> Result<()> { - // Initialize logging - tracing_subscriber::fmt() - .with_env_filter( - tracing_subscriber::EnvFilter::from_default_env() - .add_directive("stt_stream=info".parse().unwrap()), - ) - .with_writer(std::io::stderr) - .init(); - - let args = Args::parse(); - info!("Starting stt-stream with mode: {:?}", args.mode); - - // Load Whisper model - let model_path = get_model_path(&args).context("Failed to get model path")?; - info!("Loading Whisper model from: {}", model_path); - - let ctx_params = WhisperContextParameters::default(); - let whisper_ctx = WhisperContext::new_with_params(&model_path, ctx_params) - .context("Failed to load Whisper model")?; - - let whisper_ctx = Arc::new(Mutex::new(whisper_ctx)); - - // Audio capture setup - let host = cpal::default_host(); - let device = host - .default_input_device() - .context("No input device available")?; - - info!("Using input device: {}", device.name().unwrap_or_default()); - - let config = device.default_input_config()?; - let sample_rate = config.sample_rate().0; - let channels = config.channels() as usize; - - info!("Input config: {}Hz, {} channels", sample_rate, channels); - - // Resampler: input rate -> 16kHz - let resampler = if sample_rate != 16000 { - Some(Arc::new(Mutex::new( - FftFixedInOut::::new(sample_rate as usize, 16000, 1024, 1) - .context("Failed to create resampler")?, - ))) - } else { - None - }; - - // Shared state - let audio_state = Arc::new(Mutex::new(AudioState::new())); - let running = Arc::new(AtomicBool::new(true)); - let mode = Arc::new(Mutex::new(args.mode)); - - // Channel for audio data - let (audio_tx, mut audio_rx) = mpsc::channel::>(100); - - // Audio callback - let resampler_clone = resampler.clone(); - let running_clone = running.clone(); - - let stream = device.build_input_stream( - &config.into(), - move |data: &[f32], _: &cpal::InputCallbackInfo| { - if !running_clone.load(Ordering::Relaxed) { - return; - } - - // Convert to mono if needed - let mono: Vec = if channels > 1 { - data.chunks(channels) - .map(|frame| frame.iter().sum::() / channels as f32) - .collect() - } else { - data.to_vec() - }; - - // Resample if needed - let resampled = if let Some(ref resampler) = resampler_clone { - if let Ok(mut r) = resampler.lock() { - // Pad input to required length - let input_frames = r.input_frames_next(); - if mono.len() >= input_frames { - let input = vec![mono[..input_frames].to_vec()]; - match r.process(&input, None) { - Ok(output) => output.into_iter().flatten().collect(), - Err(_) => return, - } - } else { - return; - } - } else { - return; - } - } else { - mono - }; - - let _ = audio_tx.blocking_send(resampled); - }, - |err| { - error!("Audio stream error: {}", err); - }, - None, - )?; - - stream.play()?; - emit_event(&SttEvent::Ready); - - // Stdin command reader - let running_stdin = running.clone(); - let mode_stdin = mode.clone(); - let audio_state_stdin = audio_state.clone(); - - let stdin_handle = std::thread::spawn(move || { - let stdin = std::io::stdin(); - for line in stdin.lock().lines() { - if !running_stdin.load(Ordering::Relaxed) { - break; - } - - let line = match line { - Ok(l) => l, - Err(_) => continue, - }; - - let cmd: SttCommand = match serde_json::from_str(&line) { - Ok(c) => c, - Err(_) => { - // Try simple text commands - match line.trim().to_lowercase().as_str() { - "start" => SttCommand::Start, - "stop" => SttCommand::Stop, - "cancel" => SttCommand::Cancel, - "shutdown" | "quit" | "exit" => SttCommand::Shutdown, - _ => continue, - } - } - }; - - match cmd { - SttCommand::Start => { - if let Ok(mut state) = audio_state_stdin.lock() { - state.is_recording = true; - state.clear(); - emit_event(&SttEvent::RecordingStarted); - } - } - SttCommand::Stop => { - if let Ok(mut state) = audio_state_stdin.lock() { - state.is_recording = false; - emit_event(&SttEvent::RecordingStopped); - } - } - SttCommand::Cancel => { - if let Ok(mut state) = audio_state_stdin.lock() { - state.is_recording = false; - state.clear(); - emit_event(&SttEvent::RecordingStopped); - } - } - SttCommand::Shutdown => { - running_stdin.store(false, Ordering::Relaxed); - break; - } - SttCommand::SetMode { mode: m } => { - if let Ok(mut current_mode) = mode_stdin.lock() { - *current_mode = match m.as_str() { - "oneshot" => Mode::Oneshot, - "continuous" => Mode::Continuous, - "manual" => Mode::Manual, - _ => continue, - }; - } - } - } - } - }); - - // Main processing loop - let vad_threshold = args.vad_threshold; - let silence_samples_threshold = (args.silence_ms as f32 * 16.0) as usize; // 16 samples per ms at 16kHz - let partial_interval = std::time::Duration::from_millis(args.partial_interval_ms); - let emit_partials = args.partials; - let language = args.language.clone(); - - while running.load(Ordering::Relaxed) { - // Receive audio data - let samples = match tokio::time::timeout( - std::time::Duration::from_millis(100), - audio_rx.recv(), - ) - .await - { - Ok(Some(s)) => s, - Ok(None) => break, - Err(_) => continue, // Timeout, check running flag - }; - - let current_mode = *mode.lock().unwrap(); - let mut state = audio_state.lock().unwrap(); - - // Mode-specific behavior - match current_mode { - Mode::Manual => { - if !state.is_recording { - continue; - } - } - Mode::Oneshot | Mode::Continuous => { - // Auto-start on speech detection - let has_speech = simple_vad(&samples, vad_threshold); - - if !state.is_recording && has_speech { - state.is_recording = true; - state.clear(); - emit_event(&SttEvent::RecordingStarted); - } - - if !state.is_recording { - continue; - } - } - } - - // Accumulate audio - state.buffer.extend_from_slice(&samples); - - // VAD check - let has_speech = simple_vad(&samples, vad_threshold); - if has_speech { - state.speech_detected = true; - state.silence_samples = 0; - } else { - state.silence_samples += samples.len(); - } - - // Emit partial transcript if enabled - if emit_partials - && state.speech_detected - && state.last_partial.elapsed() > partial_interval - && state.buffer.len() > 16000 // At least 1 second - { - state.last_partial = std::time::Instant::now(); - let buffer_copy = state.buffer.clone(); - let ctx = whisper_ctx.clone(); - let lang = language.clone(); - - // Transcribe in background - tokio::task::spawn_blocking(move || { - if let Ok(text) = transcribe(&ctx, &buffer_copy, &lang, false) { - if !text.is_empty() { - emit_event(&SttEvent::Partial { text }); - } - } - }); - } - - // Check for end of utterance - let should_finalize = match current_mode { - Mode::Manual => !state.is_recording && state.speech_detected, - Mode::Oneshot | Mode::Continuous => { - state.speech_detected && state.silence_samples > silence_samples_threshold - } - }; - - if should_finalize && !state.buffer.is_empty() { - let buffer_copy = state.buffer.clone(); - let ctx = whisper_ctx.clone(); - let lang = language.clone(); - - // Final transcription - match transcribe(&ctx, &buffer_copy, &lang, true) { - Ok(text) => { - if !text.is_empty() { - emit_event(&SttEvent::Final { text }); - } - } - Err(e) => { - emit_event(&SttEvent::Error { - message: e.to_string(), - }); - } - } - - state.clear(); - state.is_recording = current_mode == Mode::Continuous; - - if current_mode == Mode::Oneshot { - emit_event(&SttEvent::RecordingStopped); - } - } - - // Prevent buffer from growing too large - if state.buffer.len() > 16000 * 30 { - warn!("Buffer too large, truncating"); - let start = state.buffer.len() - 16000 * 20; - state.buffer = state.buffer[start..].to_vec(); - } - } - - // Cleanup - drop(stream); - emit_event(&SttEvent::Shutdown); - let _ = stdin_handle.join(); - - Ok(()) -} - -/// Transcribe audio buffer using Whisper -fn transcribe( - ctx: &Arc>, - samples: &[f32], - language: &str, - is_final: bool, -) -> Result { - let ctx = ctx.lock().map_err(|_| anyhow::anyhow!("Lock poisoned"))?; - let mut state = ctx.create_state()?; - - let mut params = FullParams::new(SamplingStrategy::Greedy { best_of: 1 }); - - // Configure for speed vs accuracy - if is_final { - params.set_n_threads(4); - } else { - params.set_n_threads(2); - params.set_no_context(true); - } - - params.set_language(Some(language)); - params.set_print_special(false); - params.set_print_progress(false); - params.set_print_realtime(false); - params.set_print_timestamps(false); - params.set_suppress_blank(true); - params.set_suppress_non_speech_tokens(true); - - // Run inference - state.full(params, samples)?; - - // Collect segments - let num_segments = state.full_n_segments()?; - let mut text = String::new(); - - for i in 0..num_segments { - if let Ok(segment) = state.full_get_segment_text(i) { - text.push_str(&segment); - } - } - - Ok(text.trim().to_string()) -} - -/// Stub for dirs crate functionality -mod dirs { - use std::path::PathBuf; - - pub fn cache_dir() -> Option { - std::env::var("XDG_CACHE_HOME") - .map(PathBuf::from) - .ok() - .or_else(|| { - std::env::var("HOME") - .map(|h| PathBuf::from(h).join(".cache")) - .ok() - }) - } -} diff --git a/hosts/lio/flake.lock b/hosts/lio/flake.lock index 3ff8fa39..8e8563ce 100644 --- a/hosts/lio/flake.lock +++ b/hosts/lio/flake.lock @@ -87,21 +87,6 @@ "type": "github" } }, - "crane_2": { - "locked": { - "lastModified": 1768319649, - "narHash": "sha256-VFkNyxHxkqGp8gf8kfFMW1j6XeBy609kv6TE9uF/0Js=", - "owner": "ipetkov", - "repo": "crane", - "rev": "4b6527687cfd20da3c2ef8287e01b74c2d6c705b", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, "darwin": { "inputs": { "nixpkgs": [ @@ -131,14 +116,20 @@ "plasma-manager": "plasma-manager" }, "locked": { - "path": "../../flakes/de_plasma", - "type": "path" + "dir": "flakes/de_plasma", + "lastModified": 1768233301, + "narHash": "sha256-m7Og7WuCT8VdQdLhsR6J7ZCR+aFM5ddJ7A1Kt2LBXQs=", + "ref": "refs/heads/master", + "rev": "128209e4aa8927b7514bcfd2acaf097ac0d59310", + "revCount": 1122, + "type": "git", + "url": "https://git.joshuabell.xyz/ringofstorms/dotfiles" }, "original": { - "path": "../../flakes/de_plasma", - "type": "path" - }, - "parent": [] + "dir": "flakes/de_plasma", + "type": "git", + "url": "https://git.joshuabell.xyz/ringofstorms/dotfiles" + } }, "flake-utils": { "inputs": { @@ -158,24 +149,6 @@ "type": "github" } }, - "flake-utils_2": { - "inputs": { - "systems": "systems_3" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "flatpaks": { "inputs": { "nix-flatpak": "nix-flatpak" @@ -388,22 +361,6 @@ "type": "github" } }, - "nixpkgs_7": { - "locked": { - "lastModified": 1768127708, - "narHash": "sha256-1Sm77VfZh3mU0F5OqKABNLWxOuDeHIlcFjsXeeiPazs=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "ffbc9f8cbaacfb331b6017d5a5abb21a492c9a38", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, "nvim_plugin-Almo7aya/openingh.nvim": { "flake": false, "locked": { @@ -1340,8 +1297,7 @@ "opencode": "opencode", "ros_neovim": "ros_neovim", "secrets": "secrets", - "secrets-bao": "secrets-bao", - "stt_ime": "stt_ime" + "secrets-bao": "secrets-bao" } }, "ros_neovim": { @@ -1491,22 +1447,6 @@ }, "parent": [] }, - "stt_ime": { - "inputs": { - "crane": "crane_2", - "flake-utils": "flake-utils_2", - "nixpkgs": "nixpkgs_7" - }, - "locked": { - "path": "../../flakes/stt_ime", - "type": "path" - }, - "original": { - "path": "../../flakes/stt_ime", - "type": "path" - }, - "parent": [] - }, "systems": { "locked": { "lastModified": 1681028828, @@ -1536,21 +1476,6 @@ "repo": "default", "type": "github" } - }, - "systems_3": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } } }, "root": "root", diff --git a/hosts/lio/flake.nix b/hosts/lio/flake.nix index c7b16aeb..45954158 100644 --- a/hosts/lio/flake.nix +++ b/hosts/lio/flake.nix @@ -16,10 +16,8 @@ flatpaks.url = "git+https://git.joshuabell.xyz/ringofstorms/dotfiles?dir=flakes/flatpaks"; # beszel.url = "path:../../flakes/beszel"; beszel.url = "git+https://git.joshuabell.xyz/ringofstorms/dotfiles?dir=flakes/beszel"; - de_plasma.url = "path:../../flakes/de_plasma"; - # de_plasma.url = "git+https://git.joshuabell.xyz/ringofstorms/dotfiles?dir=flakes/de_plasma"; - stt_ime.url = "path:../../flakes/stt_ime"; - # stt_ime.url = "git+https://git.joshuabell.xyz/ringofstorms/dotfiles?dir=flakes/stt_ime"; + # de_plasma.url = "path:../../flakes/de_plasma"; + de_plasma.url = "git+https://git.joshuabell.xyz/ringofstorms/dotfiles?dir=flakes/de_plasma"; opencode.url = "github:sst/opencode?ref=latest"; ros_neovim.url = "git+https://git.joshuabell.xyz/ringofstorms/nvim"; @@ -71,14 +69,6 @@ # sddm.autologinUser = "josh"; }; }) - inputs.stt_ime.nixosModules.default - ({ - ringofstorms.sttIme = { - enable = true; - useGpu = true; - }; - }) - secrets.nixosModules.default ros_neovim.nixosModules.default ({