### Install Rust and Tauri CLI Source: https://github.com/aluzed/light-whisper/blob/main/README.md Installs Rust using the official script and then installs the Tauri CLI for building Tauri applications. ```bash curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh cargo install tauri-cli --version "^2" ``` -------------------------------- ### Install Linux Dependencies (Ubuntu) Source: https://github.com/aluzed/light-whisper/blob/main/README.md Installs necessary development libraries for building Tauri applications on Ubuntu 22.04+ or Debian 12+. ```bash sudo apt-get install -y \ libgtk-3-dev \ libwebkit2gtk-4.1-dev \ libayatana-appindicator3-dev \ librsvg2-dev \ libssl-dev \ libasound2-dev \ libxdo-dev \ cmake \ build-essential ``` -------------------------------- ### Install Linux Dependencies (Fedora) Source: https://github.com/aluzed/light-whisper/blob/main/README.md Installs necessary development libraries for building Tauri applications on Fedora 39+. ```bash sudo dnf install -y \ gtk3-devel \ webkit2gtk4.1-devel \ libayatana-appindicator-gtk3 \ librsvg2-devel \ openssl-devel \ alsa-lib-devel \ libxdo-devel \ cmake \ gcc-c++ ``` -------------------------------- ### Install CMake on macOS Source: https://github.com/aluzed/light-whisper/blob/main/README.md Installs Homebrew if not already present, then installs CMake, a dependency for building C/C++ projects like whisper.cpp. ```bash # Optional if you already have homebrew /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" brew install cmake ``` -------------------------------- ### GET get_config Source: https://context7.com/aluzed/light-whisper/llms.txt Retrieves the current application configuration including audio device, STT engine, model size, language, and keyboard shortcut. ```APIDOC ## GET get_config ### Description Retrieves the current application configuration including audio device, STT engine selection, model size, language preference, and keyboard shortcut settings. ### Method GET ### Endpoint get_config ### Response #### Success Response (200) - **audio_device** (string) - Audio input device name or "default" - **model_size** (string) - Whisper model: "tiny", "base", "small", "medium" - **language** (string) - Language code: "auto", "en", "fr", etc. - **engine** (string) - STT engine: "whisper" or "parakeet" - **shortcut** (string) - Global hotkey in Tauri shortcut format #### Response Example { "audio_device": "default", "model_size": "base", "language": "auto", "engine": "whisper", "shortcut": "Alt+Space" } ``` -------------------------------- ### Get Application Configuration Source: https://context7.com/aluzed/light-whisper/llms.txt Retrieves the current application settings, including audio device, STT engine, model size, language, and hotkey. Use this to display current preferences or to initialize application state. ```javascript const { invoke } = window.__TAURI__.core; // Get current configuration const config = await invoke('get_config'); // Returns: AppConfig object // { // audio_device: "default", // Audio input device name or "default" // model_size: "base", // Whisper model: "tiny", "base", "small", "medium" // language: "auto", // Language code: "auto", "en", "fr", etc. // engine: "whisper", // STT engine: "whisper" or "parakeet" // shortcut: "Alt+Space" // Global hotkey in Tauri shortcut format // } console.log(`Using engine: ${config.engine}`); console.log(`Model size: ${config.model_size}`); console.log(`Language: ${config.language}`); ``` -------------------------------- ### GET list_audio_devices Source: https://context7.com/aluzed/light-whisper/llms.txt Returns a list of available audio input devices on the system. ```APIDOC ## GET list_audio_devices ### Description Returns a list of available audio input devices on the system for microphone selection in settings. ### Method GET ### Endpoint list_audio_devices ### Response #### Success Response (200) - **devices** (array) - A list of strings representing available audio input device names. #### Response Example ["MacBook Pro Microphone", "External USB Microphone", "AirPods Pro"] ``` -------------------------------- ### Handle Recording Start/Stop Events Source: https://context7.com/aluzed/light-whisper/llms.txt Listens for 'recording-started' and 'recording-stopped' IPC events to update UI elements like timers and reset the waveform. A timer is started on 'recording-started' and cleared on 'recording-stopped'. ```javascript const { event } = window.__TAURI__; let timerInterval = null; let startTime = null; event.listen('recording-started', () => { startTime = Date.now(); timerInterval = setInterval(() => { const elapsed = Math.floor((Date.now() - startTime) / 1000); const mins = Math.floor(elapsed / 60); const secs = elapsed % 60; document.getElementById('timer').textContent = `${mins}:${secs.toString().padStart(2, '0')}`; }, 200); }); event.listen('recording-stopped', () => { clearInterval(timerInterval); document.getElementById('timer').textContent = '0:00'; }); ``` -------------------------------- ### Initialize and Use SttEngine Source: https://context7.com/aluzed/light-whisper/llms.txt Provides a unified interface for Whisper and Parakeet backends. Models must be loaded before transcription. ```rust use crate::stt::SttEngine; use std::path::Path; // Create engine from config name let mut engine = SttEngine::from_engine_name("whisper"); // or "parakeet" // Or create specific engine type let mut whisper = SttEngine::new_whisper(); let mut parakeet = SttEngine::new_parakeet(); // Load model let model_path = Path::new("/Users/user/lightwhisper/models/ggml-base.bin"); engine.load_model(model_path)?; // Check if model is loaded if engine.is_loaded() { // Transcribe 16kHz mono f32 samples let samples_16k: Vec = /* resampled audio */; // Language: "auto", "en", "fr", etc. (Parakeet ignores this - auto-detects) let text = engine.transcribe(&samples_16k, "auto")?; println!("Transcription: {}", text); } ``` -------------------------------- ### Build and Run Commands Source: https://github.com/aluzed/light-whisper/blob/main/CLAUDE.md Standard commands for development, production, and debugging of the Tauri application. ```bash # Development (hot reload frontend, debug backend) cargo tauri dev # Production build (creates .app + .dmg on macOS) cargo tauri build # Debug build (faster, no bundling optimization) cargo tauri build --debug # Build just the Rust backend (no frontend bundling) cd src-tauri && cargo build ``` -------------------------------- ### Build and Run Tauri Applications Source: https://github.com/aluzed/light-whisper/blob/main/README.md Commands for developing, building production, and debugging Tauri applications. Includes a command to build only the Rust backend. ```bash # Development (hot reload frontend, debug backend) cargo tauri dev # Production build (creates .app + .dmg on macOS, .msi on Windows) cargo tauri build # Debug build (faster, no bundling optimization) cargo tauri build --debug # Rust backend only (no frontend bundling) cd src-tauri && cargo build ``` -------------------------------- ### Manage Application Configuration Source: https://context7.com/aluzed/light-whisper/llms.txt Handles loading and saving of JSON configuration files and provides helpers for directory paths. ```rust use crate::config::{AppConfig, load_config, save_config_to_disk}; // Load config (returns defaults if file doesn't exist) let config = load_config(); // Default values: // AppConfig { // audio_device: "default", // model_size: "base", // language: "auto", // engine: "whisper", // shortcut: "Alt+Space", // } // Save modified config let mut config = load_config(); config.engine = "parakeet".to_string(); config.language = "fr".to_string(); save_config_to_disk(&config)?; // Directory paths use crate::config::{config_dir, models_dir, parakeet_models_dir}; let cfg_dir = config_dir(); // ~/lightwhisper/ let models = models_dir(); // ~/lightwhisper/models/ let parakeet = parakeet_models_dir(); // ~/lightwhisper/models/parakeet-tdt/ // Ensure all directories exist crate::config::ensure_dirs(); ``` -------------------------------- ### Manage Application Focus (macOS) Source: https://context7.com/aluzed/light-whisper/llms.txt Track and restore the previously focused application's PID before recording and activate it afterward. Ensure accessibility permissions are granted on macOS. ```rust use crate::paste::{get_frontmost_pid, activate_pid}; // Get PID of currently focused application (before showing overlay) let previous_pid = get_frontmost_pid(); // Returns i32, -1 if failed // After recording/transcription, restore focus if previous_pid > 0 { activate_pid(previous_pid); } // Check accessibility permission (macOS only) use crate::paste::ensure_accessibility_permission; let is_trusted = ensure_accessibility_permission(); // If false, macOS will prompt user to grant permission ``` -------------------------------- ### Configuration Management Source: https://context7.com/aluzed/light-whisper/llms.txt Manages application configuration stored as JSON at ~/lightwhisper/config.json. ```APIDOC ## AppConfig ### Description Handles loading and saving of application settings and directory management. ### Methods - **load_config()**: Loads configuration from disk or returns defaults. - **save_config_to_disk(config: &AppConfig)**: Persists modified configuration to disk. - **config_dir()**: Returns the configuration directory path. - **models_dir()**: Returns the models directory path. - **ensure_dirs()**: Ensures all required application directories exist. ``` -------------------------------- ### Storage Directory Structure Source: https://github.com/aluzed/light-whisper/blob/main/CLAUDE.md Layout of the application's configuration, model, and temporary file storage. ```text ~/lightwhisper/ ├── config.json # {audio_device, model_size, language} ├── models/ggml-{size}.bin # Downloaded whisper.cpp models └── temp/ # Temporary WAV files (macOS/Linux) ``` -------------------------------- ### Configure ParakeetEngine Source: https://context7.com/aluzed/light-whisper/llms.txt Interface for NVIDIA Parakeet TDT using ONNX Runtime. Requires a directory containing encoder, decoder, and vocabulary files. ```rust use crate::stt::ParakeetEngine; use std::path::Path; let mut parakeet = ParakeetEngine::new(); // Load from directory containing encoder, decoder, and vocab files let model_dir = Path::new("~/lightwhisper/models/parakeet-tdt/"); // Required files: // - encoder-model.onnx // - decoder_joint-model.onnx // - vocab.txt parakeet.load_model(model_dir)?; // Transcribe (language parameter ignored - auto-detection) let samples: &[f32] = /* 16kHz mono audio */; let text = parakeet.transcribe(samples, "auto")?; // Supports 25 European languages with automatic detection ``` -------------------------------- ### POST save_config Source: https://context7.com/aluzed/light-whisper/llms.txt Saves the application configuration to disk and reloads the STT engine if necessary. ```APIDOC ## POST save_config ### Description Saves the application configuration to disk and reloads the STT engine if the engine type or model size changed. ### Method POST ### Endpoint save_config ### Parameters #### Request Body - **config** (object) - Required - The configuration object containing audio_device, model_size, language, engine, and shortcut. ### Request Example { "config": { "audio_device": "MacBook Pro Microphone", "model_size": "small", "language": "en", "engine": "whisper", "shortcut": "Alt+Space" } } ``` -------------------------------- ### Listen for Model Download Progress Source: https://context7.com/aluzed/light-whisper/llms.txt Listens for 'download-progress' and 'download-complete' IPC events during model downloads. Updates a progress bar and text to show download status. ```javascript const { event } = window.__TAURI__; event.listen('download-progress', (e) => { const { percent, downloaded_mb, total_mb } = e.payload; // percent: 0-100 float // downloaded_mb: bytes downloaded in MB // total_mb: total file size in MB document.getElementById('progress-bar').style.width = `${percent}%`; document.getElementById('progress-text').textContent = `${downloaded_mb.toFixed(1)} / ${total_mb.toFixed(1)} MB (${percent.toFixed(0)}%)`; }); event.listen('download-complete', () => { console.log('Model download finished'); }); ``` -------------------------------- ### Application Data Flow Source: https://github.com/aluzed/light-whisper/blob/main/CLAUDE.md Visual representation of the recording and transcription process triggered by shortcuts. ```text Alt+Space → do_toggle_recording() → AudioRecorder.start() → cpal captures on dedicated thread → Arc>> → emits "waveform-update" events to frontend Alt+Space again → AudioRecorder.stop() → thread joins → resample to 16kHz → WhisperEngine.transcribe() → paste::paste_text() (clipboard + Cmd/Ctrl+V simulation) ``` -------------------------------- ### Configure WhisperEngine Source: https://context7.com/aluzed/light-whisper/llms.txt Direct interface for Whisper models using whisper-rs. Supports language hints for transcription. ```rust use crate::stt::WhisperEngine; use std::path::Path; let mut whisper = WhisperEngine::new(); // Load GGML model file whisper.load_model(Path::new("~/lightwhisper/models/ggml-base.bin"))?; // Transcribe with language hint let samples: &[f32] = /* 16kHz mono audio */; let text = whisper.transcribe(samples, "en")?; // "auto" for auto-detection // Internally uses: // - SamplingStrategy::Greedy { best_of: 1 } // - 4 threads // - suppress_blank: true // - single_segment: false ``` -------------------------------- ### Record Audio with AudioRecorder Source: https://context7.com/aluzed/light-whisper/llms.txt Captures microphone input on a dedicated thread. Requires a tauri::AppHandle for event emission. ```rust use crate::audio::AudioRecorder; use tauri::AppHandle; // Create a new recorder instance let mut recorder = AudioRecorder::new(); // Start recording on specified device // Emits "waveform-update" and "recording-started" events recorder.start("default", app_handle.clone())?; // Or use specific device name: // recorder.start("MacBook Pro Microphone", app_handle.clone())?; // Check if currently recording if recorder.is_recording() { println!("Recording in progress..."); } // Stop recording and get audio samples // Returns (samples: Vec, sample_rate: u32) let (samples, sample_rate) = recorder.stop()?; // samples: mono f32 audio at device's native sample rate // sample_rate: e.g., 44100, 48000 // Resample to 16kHz for STT engines let samples_16k = crate::audio::resample(&samples, sample_rate, 16000); ``` -------------------------------- ### List Available Audio Input Devices Source: https://context7.com/aluzed/light-whisper/llms.txt Retrieves a list of all available audio input devices on the system. This is useful for populating a dropdown menu in the settings to allow users to select their preferred microphone. ```javascript const { invoke } = window.__TAURI__.core; // Get all available input devices const devices = await invoke('list_audio_devices'); // Returns: string[] // ["MacBook Pro Microphone", "External USB Microphone", "AirPods Pro"] // Populate a dropdown const audioDeviceSelect = document.getElementById('audio-device'); audioDeviceSelect.innerHTML = ''; devices.forEach(device => { const opt = document.createElement('option'); opt.value = device; opt.textContent = device; audioDeviceSelect.appendChild(opt); }); ``` -------------------------------- ### POST /download_model Source: https://context7.com/aluzed/light-whisper/llms.txt Downloads the specified STT model from HuggingFace with streaming progress events emitted during download. ```APIDOC ## POST /download_model ### Description Downloads the specified STT model from HuggingFace with streaming progress events emitted during download. ### Method POST ### Endpoint /download_model ### Parameters #### Request Body - **engine** (string) - Required - The STT engine to download the model for (e.g., "whisper", "parakeet"). - **modelSize** (string) - Optional - The size of the model to download (e.g., "tiny", "base", "small", "medium"). This parameter is ignored for the "parakeet" engine. ### Request Example ```json { "engine": "whisper", "modelSize": "base" } ``` ### Response #### Success Response (200) This endpoint does not return a specific success response body, but emits `download-progress` and `download-complete` IPC events. #### Error Response - **400 Bad Request**: If required parameters are missing or invalid. - **500 Internal Server Error**: If the download fails on the server side. ``` -------------------------------- ### Save Application Configuration Source: https://context7.com/aluzed/light-whisper/llms.txt Saves new application settings to disk. The STT engine will automatically reload if the engine type or model size has changed. Configuration is persisted to ~/lightwhisper/config.json. ```javascript const { invoke } = window.__TAURI__.core; // Save new configuration await invoke('save_config', { config: { audio_device: "MacBook Pro Microphone", model_size: "small", language: "en", engine: "whisper", shortcut: "Alt+Space" } }); // Engine is automatically reloaded if engine type or model changed // Config is persisted to ~/lightwhisper/config.json ``` -------------------------------- ### POST /change_shortcut Source: https://context7.com/aluzed/light-whisper/llms.txt Changes the global hotkey used to toggle voice recording. Unregisters all existing shortcuts and registers the new one. ```APIDOC ## POST /change_shortcut ### Description Changes the global hotkey used to toggle voice recording. Unregisters all existing shortcuts and registers the new one. ### Method POST ### Endpoint /change_shortcut ### Parameters #### Request Body - **shortcut** (string) - Required - The new hotkey to set. Supported format: `Modifier+Key` (e.g., "Ctrl+Shift+R", "Alt+Space"). Modifiers include Ctrl, Alt, Shift, Super (Meta/Cmd). Keys include A-Z, 0-9, F1-F12, Space, etc. ### Request Example ```json { "shortcut": "Ctrl+Shift+R" } ``` ### Response #### Success Response (200) Indicates the shortcut was successfully changed. #### Error Response - **400 Bad Request**: If the provided shortcut format is invalid. ``` -------------------------------- ### Link and Image Styling Source: https://github.com/aluzed/light-whisper/blob/main/docs/index.html Basic styling for anchor tags to inherit color and remove underlines, and for images to ensure they are responsive within their containers. ```css a { text-decoration: none; color: inherit; } img { max-width: 100%; } ``` -------------------------------- ### Download STT Models Source: https://context7.com/aluzed/light-whisper/llms.txt Download STT models (Whisper and Parakeet) from HuggingFace with progress events. Check if models already exist before downloading. ```rust use crate::model_manager::{ download_whisper_model, download_parakeet_model, whisper_model_exists, parakeet_model_exists, model_exists_for_engine, }; use tauri::AppHandle; // Check if models exist let has_whisper_base = whisper_model_exists("base"); let has_parakeet = parakeet_model_exists(); let has_model = model_exists_for_engine("whisper", "small"); // Download Whisper model (async) let model_path = download_whisper_model("base", app_handle.clone()).await?; // Emits: download-progress, download-complete events // Returns: PathBuf to ~/lightwhisper/models/ggml-base.bin // Download Parakeet model (async, downloads 3 files) let model_dir = download_parakeet_model(app_handle.clone()).await?; // Emits: download-file-info (per file), download-progress, download-complete // Returns: PathBuf to ~/lightwhisper/models/parakeet-tdt/ ``` -------------------------------- ### AudioRecorder API Source: https://context7.com/aluzed/light-whisper/llms.txt The AudioRecorder module provides thread-safe audio capture from the microphone using cpal. ```APIDOC ## AudioRecorder ### Description Thread-safe audio recorder that captures microphone input on a dedicated thread using cpal. ### Methods - **new()**: Creates a new recorder instance. - **start(device_name: &str, app_handle: AppHandle)**: Starts recording on the specified device. Emits "waveform-update" and "recording-started" events. - **is_recording()**: Returns true if currently recording. - **stop()**: Stops recording and returns a tuple of (samples: Vec, sample_rate: u32). ``` -------------------------------- ### Download STT Models Source: https://context7.com/aluzed/light-whisper/llms.txt Downloads specified STT models from HuggingFace. Listen for 'download-progress' and 'download-complete' events for status updates. Supports Whisper and Parakeet engines. ```javascript const { invoke } = window.__TAURI__.core; const { event } = window.__TAURI__; // Listen for download progress events event.listen('download-progress', (e) => { const { percent, downloaded_mb, total_mb } = e.payload; console.log(`${downloaded_mb.toFixed(1)}/${total_mb.toFixed(1)} MB (${percent.toFixed(0)}%)`); progressBar.style.width = `${percent}%`; }); // Listen for multi-file download info (Parakeet only) event.listen('download-file-info', (e) => { const { file_index, file_count, file_name } = e.payload; console.log(`Downloading file ${file_index}/${file_count}: ${file_name}`); }); event.listen('download-complete', () => { console.log('Download complete!'); }); // Download Whisper model await invoke('download_model', { engine: "whisper", modelSize: "base" // Options: "tiny", "base", "small", "medium" }); // Downloads from: https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.bin // Saves to: ~/lightwhisper/models/ggml-base.bin // Download Parakeet model (downloads 3 files: encoder, decoder, vocab) await invoke('download_model', { engine: "parakeet", modelSize: "" // modelSize is ignored for Parakeet }); // Downloads from: https://huggingface.co/istupakov/parakeet-tdt-0.6b-v3-onnx/ // Saves to: ~/lightwhisper/models/parakeet-tdt/ ``` -------------------------------- ### Paste Utility Source: https://context7.com/aluzed/light-whisper/llms.txt Utility for pasting text into the active application. ```APIDOC ## paste_text ### Description Pastes text by setting clipboard content and simulating Cmd+V (macOS) or Ctrl+V (Windows/Linux). ### Parameters - **text** (string) - Required - The text to be pasted into the active application. ``` -------------------------------- ### POST check_model_exists Source: https://context7.com/aluzed/light-whisper/llms.txt Checks whether the specified STT model has been downloaded and is available for use. ```APIDOC ## POST check_model_exists ### Description Checks whether the specified STT model has been downloaded and is available for use. ### Method POST ### Endpoint check_model_exists ### Parameters #### Request Body - **engine** (string) - Required - The STT engine name ("whisper" or "parakeet"). - **modelSize** (string) - Required - The model size (e.g., "base"). Ignored for Parakeet. ### Response #### Success Response (200) - **exists** (boolean) - True if the model files are present. ### Request Example { "engine": "whisper", "modelSize": "base" } ``` -------------------------------- ### Check STT Model Existence Source: https://context7.com/aluzed/light-whisper/llms.txt Verifies if a specified STT model (for either Whisper or Parakeet) is downloaded and available for use. For Parakeet, the modelSize parameter is ignored. ```javascript const { invoke } = window.__TAURI__.core; // Check if Whisper "base" model exists const whisperExists = await invoke('check_model_exists', { engine: "whisper", modelSize: "base" }); // Returns: boolean - true if ~/lightwhisper/models/ggml-base.bin exists // Check if Parakeet model exists const parakeetExists = await invoke('check_model_exists', { engine: "parakeet", modelSize: "" // modelSize is ignored for Parakeet }); // Returns: boolean - true if ~/lightwhisper/models/parakeet-tdt/ contains all required files if (!whisperExists) { console.log("Model not downloaded - showing download button"); } ``` -------------------------------- ### Automate Text Pasting Source: https://context7.com/aluzed/light-whisper/llms.txt Pastes text by updating the system clipboard and simulating keyboard shortcuts. ```rust use crate::paste::{paste_text, get_frontmost_pid, activate_pid}; // Paste transcribed text into active application paste_text("Hello, this is transcribed text")?; // Internally: // 1. Saves current clipboard content // 2. Sets new text to clipboard // 3. Waits 50ms for clipboard to be ready // 4. Simulates Cmd+V or Ctrl+V // 5. Waits 100ms then restores previous clipboard ``` -------------------------------- ### Base CSS Reset and Body Styles Source: https://github.com/aluzed/light-whisper/blob/main/docs/index.html Applies a CSS reset for consistent box-sizing and sets base styles for the HTML and body, including font, background, and text color, with smooth transitions for theme changes. ```css *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; } html { scroll-behavior: smooth; } body { font-family: 'Inter', system-ui, sans-serif; background: var(--bg-primary); color: var(--text-primary); line-height: 1.6; transition: background 0.3s, color 0.3s; } ``` -------------------------------- ### CSS Variables for Theming Source: https://github.com/aluzed/light-whisper/blob/main/docs/index.html Defines CSS custom properties for color schemes and UI elements, supporting light and dark themes. These variables are essential for dynamic theme switching. ```css :root { --coral: #FF6F61; --blue: #0F4C81; --yellow: #F5DF4D; --mint: #88D8B0; --lavender: #B8A9C9; --peach: #FFBE76; --sky: #7EC8E3; --rose: #F7CAC9; --shadow-offset: 5px; --radius: 14px; --radius-sm: 10px; } ``` ```css [data-theme="light"] { --bg-primary: #FAFAF8; --bg-secondary: #FFFFFF; --bg-hero: #FF6F61; --bg-features: #0F4C81; --bg-demo: #F5DF4D; --bg-engines: #88D8B0; --bg-cta: #B8A9C9; --text-primary: #1A1A2E; --text-secondary: #4A4A68; --text-on-coral: #FFFFFF; --text-on-blue: #FFFFFF; --text-on-yellow:#1A1A2E; --text-on-mint: #1A1A2E; --text-on-lavender:#1A1A2E; --shadow-color: rgba(26, 26, 46, 0.18); --shadow-hero: rgba(0,0,0,0.15); --card-bg: #FFFFFF; --card-shadow: #1A1A2E; --nav-bg: rgba(250, 250, 248, 0.92); --toggle-bg: #E8E8E4; --toggle-icon: #1A1A2E; } ``` ```css [data-theme="dark"] { --bg-primary: #111127; --bg-secondary: #1A1A3E; --bg-hero: #C04D42; --bg-features: #0A3560; --bg-demo: #B8A030; --bg-engines: #2E7D5B; --bg-cta: #6B5B8D; --text-primary: #F0F0F5; --text-secondary:#B0B0CC; --text-on-coral: #FFFFFF; --text-on-blue: #E0E8F0; --text-on-yellow:#111127; --text-on-mint: #111127; --text-on-lavender:#F0F0F5; --shadow-color: rgba(0, 0, 0, 0.35); --shadow-hero: rgba(0,0,0,0.3); --card-bg: #1E1E42; --card-shadow: #000000; --nav-bg: rgba(17, 17, 39, 0.92); --toggle-bg: #2A2A50; --toggle-icon: #F5DF4D; } ``` -------------------------------- ### STT Engine API Source: https://context7.com/aluzed/light-whisper/llms.txt Unified interface for speech-to-text transcription using Whisper or Parakeet backends. ```APIDOC ## SttEngine ### Description Unified speech-to-text engine supporting both Whisper and Parakeet backends. ### Methods - **from_engine_name(name: &str)**: Creates engine from config name ("whisper" or "parakeet"). - **load_model(path: &Path)**: Loads the model from the specified path. - **is_loaded()**: Checks if the model is loaded. - **transcribe(samples: &[f32], language: &str)**: Transcribes 16kHz mono f32 samples. Language parameter is ignored by Parakeet. ``` -------------------------------- ### Listen for Waveform Updates Source: https://context7.com/aluzed/light-whisper/llms.txt Listens for 'waveform-update' IPC events emitted during recording. These events provide RMS audio level values for real-time waveform visualization. The RMS values are amplified using a sqrt curve for better display. ```javascript const { event } = window.__TAURI__; const bars = new Array(30).fill(0); event.listen('waveform-update', (e) => { const rms = e.payload; // f32 RMS value (typically 0.002-0.05 for speech) // Amplify with sqrt curve for better visualization const display = Math.min(1.0, Math.sqrt(rms) * 4); // Shift bars left and append new value bars.shift(); bars.push(display); // Redraw waveform canvas drawWaveform(bars); }); ``` -------------------------------- ### Handle Application Errors Source: https://context7.com/aluzed/light-whisper/llms.txt Listens for 'app-error' IPC events, which are emitted when errors occur during recording, transcription, or pasting. Displays errors using a toast notification. Common errors include audio detection issues, missing models, and processing failures. ```javascript const { event } = window.__TAURI__; event.listen('app-error', (e) => { const errorMessage = e.payload; // Display toast notification with error message showToast(errorMessage); // Common errors: // - "No audio detected..." - microphone permission or device issue // - "STT engine not loaded..." - no model downloaded // - "Transcription failed..." - model processing error // - "Paste failed..." - accessibility permission needed on macOS }); ``` -------------------------------- ### Hero Section Styling Source: https://github.com/aluzed/light-whisper/blob/main/docs/index.html Styles the main hero section with a full viewport height, centered content, background gradients, and decorative pseudo-elements. It includes responsive font sizes and button styling. ```css .hero { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: var(--bg-hero); color: var(--text-on-coral); padding-top: 140px; position: relative; overflow: hidden; } .hero::before { content: ''; position: absolute; top: -60px; right: -60px; width: 300px; height: 300px; background: var(--yellow); border-radius: 50%; opacity: 0.15; } .hero::after { content: ''; position: absolute; bottom: -40px; left: -40px; width: 200px; height: 200px; background: var(--mint); border-radius: 50%; opacity: 0.12; } .hero-content { max-width: 720px; text-align: center; position: relative; z-index: 1; } .hero-badge { display: inline-block; background: rgba(255,255,255,0.2); padding: 6px 18px; border-radius: 50px; font-size: 0.85rem; font-weight: 600; margin-bottom: 28px; backdrop-filter: blur(4px); } .hero h1 { font-size: clamp(2.8rem, 6vw, 4.5rem); font-weight: 800; line-height: 1.1; margin-bottom: 20px; } .hero p { font-size: clamp(1.05rem, 2vw, 1.25rem); opacity: 0.92; max-width: 520px; margin: 0 auto 40px; line-height: 1.6; } .hero-buttons { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; } .btn { display: inline-flex; align-items: center; gap: 10px; paddin ``` -------------------------------- ### Section Base Padding Source: https://github.com/aluzed/light-whisper/blob/main/docs/index.html Sets consistent top and bottom padding for all section elements to ensure vertical spacing across the page. ```css section { padding: 100px 40px; } ``` -------------------------------- ### Resample Audio Data Source: https://context7.com/aluzed/light-whisper/llms.txt Performs linear interpolation to convert audio to 16kHz, which is required for STT engines. ```rust use crate::audio::resample; // Resample from 48kHz to 16kHz (required for Whisper/Parakeet) let samples_48k: Vec = /* audio at 48kHz */; let samples_16k = resample(&samples_48k, 48000, 16000); // No-op if rates match let same = resample(&samples_48k, 48000, 48000); // Returns clone ``` -------------------------------- ### IPC Events Source: https://context7.com/aluzed/light-whisper/llms.txt Real-time events emitted from the backend to the frontend for various application states and updates. ```APIDOC ## IPC Events (Backend to Frontend) ### `waveform-update` #### Description Emitted during recording with RMS audio level values for real-time waveform visualization. #### Payload - **rms** (f32) - The Root Mean Square audio level value. ### `recording-started` / `recording-stopped` #### Description Emitted when recording begins or ends to update UI state (timers, waveform reset). #### Payload None. ### `download-progress` / `download-complete` #### Description Emitted during model downloads with progress information. #### Payload (`download-progress`) - **percent** (f32) - Download progress percentage (0-100). - **downloaded_mb** (f32) - Amount of data downloaded in megabytes. - **total_mb** (f32) - Total file size in megabytes. #### Payload (`download-complete`) None. ### `app-error` #### Description Emitted when errors occur (recording failed, transcription failed, paste failed). #### Payload - **errorMessage** (string) - A message describing the error that occurred. ``` -------------------------------- ### Navigation Bar Styling Source: https://github.com/aluzed/light-whisper/blob/main/docs/index.html Styles the fixed navigation bar with background blur effects, logo display, navigation links, and a theme toggle button. Includes hover and active states for interactive elements. ```css nav { position: fixed; top: 0; left: 0; right: 0; z-index: 100; display: flex; align-items: center; justify-content: space-between; padding: 16px 40px; background: var(--nav-bg); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); transition: background 0.3s; } .nav-logo { font-size: 1.2rem; font-weight: 800; display: flex; align-items: center; gap: 8px; } .nav-logo svg { width: 28px; height: 28px; } .nav-links { display: flex; align-items: center; gap: 24px; } .nav-links a { font-size: 0.9rem; font-weight: 600; opacity: 0.8; transition: opacity 0.2s; } .nav-links a:hover { opacity: 1; } .theme-toggle { width: 42px; height: 42px; border-radius: 50%; border: none; cursor: pointer; background: var(--toggle-bg); color: var(--toggle-icon); display: flex; align-items: center; justify-content: center; font-size: 1.2rem; transition: background 0.3s, color 0.3s, transform 0.2s; box-shadow: 3px 3px 0 var(--shadow-color); } .theme-toggle:hover { transform: translateY(-2px); } .theme-toggle:active { transform: translate(2px, 2px); box-shadow: none; } ``` -------------------------------- ### Language Toggle Button Styling Source: https://github.com/aluzed/light-whisper/blob/main/docs/index.html Styles a language toggle component with pill-shaped buttons and active state highlighting. It uses background and text color transitions for a smooth user experience. ```css .lang-toggle { display: flex; align-items: center; gap: 6px; background: var(--toggle-bg); border-radius: 50px; padding: 4px; box-shadow: 3px 3px 0 var(--shadow-color); transition: background 0.3s; } .lang-toggle button { display: flex; align-items: center; gap: 4px; padding: 5px 12px; border: none; border-radius: 50px; font-size: 0.82rem; font-weight: 700; cursor: pointer; background: transparent; color: var(--text-secondary); transition: background 0.2s, color 0.2s, box-shadow 0.2s; } .lang-toggle button.active { background: var(--coral); color: #fff; box-shadow: 2px 2px 0 rgba(0,0,0,0.12); } .lang-toggle button:not(.active):hover { color: var(--text-primary); } ``` -------------------------------- ### Change Global Hotkey Source: https://context7.com/aluzed/light-whisper/llms.txt Changes the global hotkey for toggling voice recording. This function unregisters all existing shortcuts and registers the new one. Supported format: Modifier+Key. ```javascript const { invoke } = window.__TAURI__.core; // Change hotkey to Ctrl+Shift+R try { await invoke('change_shortcut', { shortcut: "Ctrl+Shift+R" }); console.log("Shortcut updated successfully"); } catch (e) { console.error(`Invalid shortcut: ${e}`); } // Reset to default await invoke('change_shortcut', { shortcut: "Alt+Space" }); // Supported format: Modifier+Key // Modifiers: Ctrl, Alt, Shift, Super (Meta/Cmd) // Keys: A-Z, 0-9, F1-F12, Space, etc. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.