### Install Project Requirements Source: https://github.com/savbell/whisper-writer/blob/main/README.md Installs all Python packages listed in the 'requirements.txt' file within the activated virtual environment. ```bash pip install -r requirements.txt ``` -------------------------------- ### WhisperWriter Configuration File Example Source: https://context7.com/savbell/whisper-writer/llms.txt An example `src/config.yaml` file showing production settings for model options, recording preferences, and post-processing behavior. Missing keys default to `config_schema.yaml`. ```yaml # src/config.yaml — example production configuration model_options: use_api: false common: language: en # ISO-639-1; null = auto-detect temperature: 0.0 initial_prompt: null local: model: large-v3 # tiny / base / small / medium / large-v1/v2/v3 device: cuda # auto | cuda | cpu compute_type: float16 # default | float32 | float16 | int8 condition_on_previous_text: true vad_filter: true model_path: null # set to use a pre-downloaded model recording_options: activation_key: ctrl+shift+space input_backend: auto # auto | evdev | pynput recording_mode: continuous # continuous | voice_activity_detection | press_to_toggle | hold_to_record sound_device: null # run `python -m sounddevice` to list device indices sample_rate: 16000 silence_duration: 900 # ms of silence before stopping (VAD modes) min_duration: 100 # discard recordings shorter than this (ms) post_processing: writing_key_press_delay: 0.005 remove_trailing_period: false add_trailing_space: true remove_capitalization: false input_method: pynput # pynput | ydotool | dotool misc: print_to_terminal: true hide_status_window: false noise_on_completion: false ``` -------------------------------- ### Install NVIDIA Libraries with Pip (Linux) Source: https://github.com/savbell/whisper-writer/blob/main/README.md Installs necessary NVIDIA libraries for GPU acceleration on Linux using pip. Ensure LD_LIBRARY_PATH is set correctly before running Python. ```bash pip install nvidia-cublas-cu12 nvidia-cudnn-cu12 export LD_LIBRARY_PATH=`python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))'` ``` -------------------------------- ### Run WhisperWriter Application Source: https://github.com/savbell/whisper-writer/blob/main/README.md Executes the main Python script for the WhisperWriter application. This should be run after all dependencies are installed and the virtual environment is activated. ```bash python run.py ``` -------------------------------- ### Global Hotkey Management Source: https://context7.com/savbell/whisper-writer/llms.txt Manages global hotkey detection using `EvdevBackend` (Linux) or `PynputBackend` (cross-platform). Parses activation key strings (e.g., `"ctrl+shift+space"`) into `KeyChord` and fires registered callbacks on activation and deactivation. Starts listening in a background thread. ```python from key_listener import KeyListener from utils import ConfigManager ConfigManager.initialize() listener = KeyListener() # Register callbacks for chord press and release listener.add_callback("on_activate", lambda: print("Hotkey pressed — start recording")) listener.add_callback("on_deactivate", lambda: print("Hotkey released — stop recording")) # Start listening (non-blocking; uses a background thread) listener.start() # Dynamically update activation key at runtime ConfigManager.set_config_value('ctrl+alt+space', 'recording_options', 'activation_key') listener.update_activation_keys() # Stop and release resources listener.stop() ``` -------------------------------- ### WhisperWriter Application Entry Point Source: https://context7.com/savbell/whisper-writer/llms.txt The `run.py` script initializes the WhisperWriter application, setting up the system tray, settings, main windows, and key listener. It demonstrates the application's signal flow. ```python # run.py — the application entry point import sys import os sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src')) from main import WhisperWriterApp # On first run (no src/config.yaml), the Settings window opens automatically. # On subsequent runs, the main window opens and "Start" activates the hotkey listener. app = WhisperWriterApp() app.run() # Signal flow: # KeyListener.on_activate() # → WhisperWriterApp.on_activation() # → ResultThread.start() # → ResultThread.statusSignal → StatusWindow.updateStatus() # → ResultThread.resultSignal → WhisperWriterApp.on_transcription_complete() # → InputSimulator.typewrite(result) # → (if continuous mode) ResultThread.start() again ``` -------------------------------- ### Input Simulation with Different Backends Source: https://context7.com/savbell/whisper-writer/llms.txt Demonstrates using InputSimulator with default pynput, Wayland-compatible ydotool, and persistent dotool backends. Configure `writing_key_press_delay` for inter-keystroke timing. ```python from input_simulation import InputSimulator from utils import ConfigManager ConfigManager.initialize() # Default: pynput backend, 5ms delay between keystrokes simulator = InputSimulator() simulator.typewrite("Hello, world! ") # types into the currently focused window # With ydotool (Wayland): # post_processing: # input_method: ydotool # writing_key_press_delay: 0.01 simulator_wayland = InputSimulator() simulator_wayland.typewrite("Typed via ydotool on Wayland ") # With dotool (persistent process): # post_processing: # input_method: dotool simulator_dotool = InputSimulator() simulator_dotool.typewrite("Fast dotool typing ") simulator_dotool.cleanup() # terminate the dotool subprocess ``` -------------------------------- ### Create and Activate Virtual Environment Source: https://github.com/savbell/whisper-writer/blob/main/README.md Creates a Python virtual environment named 'venv' and activates it. This isolates project dependencies. Activation commands differ for Linux/macOS and Windows. ```bash python -m venv venv # For Linux and macOS: source venv/bin/activate # For Windows: virtualenv\Scripts\activate ``` -------------------------------- ### Initialize and Access Configuration with ConfigManager Source: https://context7.com/savbell/whisper-writer/llms.txt Initialize the ConfigManager once at application startup to load default and user configurations. Access configuration values as dictionaries or individual settings. Values can be modified at runtime and persisted to disk. ```python from utils import ConfigManager # Initialize once at application startup (reads schema + user config) ConfigManager.initialize() # Read a top-level section as a dict model_options = ConfigManager.get_config_section('model_options') print(model_options['use_api']) # False print(model_options['local']['model']) # 'base' # Read a single deeply-nested value activation_key = ConfigManager.get_config_value('recording_options', 'activation_key') print(activation_key) # 'ctrl+shift+space' hide_window = ConfigManager.get_config_value('misc', 'hide_status_window') print(hide_window) # False # Write a value at runtime ConfigManager.set_config_value('large', 'model_options', 'local', 'model') print(ConfigManager.get_config_value('model_options', 'local', 'model')) # 'large' # Persist to disk ConfigManager.save_config() # writes to src/config.yaml # Reload from disk (e.g., after external edit) ConfigManager.reload_config() # Conditional terminal logging respecting the print_to_terminal setting ConfigManager.console_print('Recording started.') # prints only if enabled ``` -------------------------------- ### Create Local Whisper Model Source: https://context7.com/savbell/whisper-writer/llms.txt Instantiate a faster-whisper model using settings from the configuration. Handles device selection and provides CPU fallback on errors. Ensure ConfigManager is initialized before calling. ```python from transcription import create_local_model from utils import ConfigManager ConfigManager.initialize() # Uses config: model='base', device='auto', compute_type='default' model = create_local_model() # Output: "Creating local model..." → "Local model created." # With a custom model path configured in src/config.yaml: # model_options: # local: # model_path: /home/user/.cache/whisper/large-v3 # device: cuda # compute_type: float16 model = create_local_model() # Output: "Loading model from: /home/user/.cache/whisper/large-v3" ``` -------------------------------- ### Clone WhisperWriter Repository Source: https://github.com/savbell/whisper-writer/blob/main/README.md Clones the WhisperWriter project from GitHub and navigates into the project directory. This is the first step in setting up the project locally. ```bash git clone https://github.com/savbell/whisper-writer cd whisper-writer ``` -------------------------------- ### Real-time Transcription with PyQt5 Source: https://context7.com/savbell/whisper-writer/llms.txt Orchestrates the record → transcribe → emit pipeline using a PyQt5 `QThread`. Emits status updates and the final transcribed text. Requires `QApplication` initialization and signal/slot connections. ```python from PyQt5.QtWidgets import QApplication from PyQt5.QtCore import QTimer import sys from result_thread import ResultThread from transcription import create_local_model from utils import ConfigManager app = QApplication(sys.argv) ConfigManager.initialize() local_model = create_local_model() thread = ResultThread(local_model) def on_status(status): print(f"[STATUS] {status}") # recording → transcribing → idle def on_result(text): print(f"[RESULT] {text}") app.quit() thread.statusSignal.connect(on_status) thread.resultSignal.connect(on_result) # Start recording; in press_to_toggle mode, stop it after 3 seconds thread.start() QTimer.singleShot(3000, thread.stop_recording) app.exec_() ``` -------------------------------- ### Transcribe Audio via API Source: https://context7.com/savbell/whisper-writer/llms.txt Configures the system to use the OpenAI API for transcription. Ensure `model_options.use_api` is true and `model_options.api.api_key` is set. Supports both direct API calls and local OpenAI-compatible servers. ```python ConfigManager.initialize() sample_rate = 16000 audio_data = sd.rec(int(3 * sample_rate), samplerate=sample_rate, channels=1, dtype='int16') sd.wait() audio_data = audio_data[:, 0] result = transcribe_api(audio_data) print(result) # "This text was transcribed via the OpenAI API." # Using a local OpenAI-compatible server (e.g., LocalAI): # model_options: # api: # base_url: http://localhost:8080/v1 # api_key: localai # model: whisper-1 result = transcribe_api(audio_data) print(result) # transcribed by local server ``` -------------------------------- ### Top-Level Transcription Dispatcher Source: https://context7.com/savbell/whisper-writer/llms.txt Routes audio data to either the API or a local model based on `model_options.use_api`. The raw transcription result is then passed through `post_process_transcription`. Handles `None` input gracefully by returning an empty string. ```python import numpy as np import sounddevice as sd from transcription import transcribe, create_local_model from utils import ConfigManager ConfigManager.initialize() local_model = create_local_model() sample_rate = 16000 audio_data = sd.rec(int(3 * sample_rate), samplerate=sample_rate, channels=1, dtype='int16') sd.wait() audio_data = audio_data[:, 0] # Routes to local model (use_api=False by default) result = transcribe(audio_data, local_model) print(result) # "Transcribed text with trailing space " # Returns empty string gracefully when audio_data is None result = transcribe(None, local_model) print(repr(result)) # '' ``` -------------------------------- ### Transcribe Audio via API Source: https://context7.com/savbell/whisper-writer/llms.txt Encode a NumPy int16 audio array into a WAV file and send it to the OpenAI Audio Transcriptions endpoint. The base URL and model can be configured for use with local OpenAI-compatible servers. ```python import numpy as np import sounddevice as sd from transcription import transcribe_api from utils import ConfigManager ``` -------------------------------- ### Transcribe Audio Locally Source: https://context7.com/savbell/whisper-writer/llms.txt Transcribe a NumPy int16 audio array using a local faster-whisper model. The function handles audio conversion, VAD filtering, and text segment joining. Optionally, a local model can be created on the fly if not provided. ```python import numpy as np import sounddevice as sd from transcription import transcribe_local, create_local_model from utils import ConfigManager ConfigManager.initialize() model = create_local_model() # Capture 3 seconds of audio at 16 kHz sample_rate = 16000 duration = 3 audio_data = sd.rec(int(duration * sample_rate), samplerate=sample_rate, channels=1, dtype='int16') sd.wait() audio_data = audio_data[:, 0] # flatten to 1D int16 array result = transcribe_local(audio_data, local_model=model) print(result) # e.g. "Hello, this is a test transcription." # Without passing a model — creates one on the fly (slower): result = transcribe_local(audio_data) print(result) ``` -------------------------------- ### Post-process Transcription Text Source: https://context7.com/savbell/whisper-writer/llms.txt Applies text cleanup rules such as stripping whitespace, removing trailing periods, adding trailing spaces, and lowercasing. These rules are configured under `post_processing` and are automatically applied by the `transcribe()` function. ```python from transcription import post_process_transcription from utils import ConfigManager ConfigManager.initialize() # Default config: add_trailing_space=True, remove_trailing_period=False, remove_capitalization=False raw = " Hello, how are you. " result = post_process_transcription(raw) print(repr(result)) # 'Hello, how are you. ' # With remove_trailing_period=True and remove_capitalization=True: ConfigManager.set_config_value(True, 'post_processing', 'remove_trailing_period') ConfigManager.set_config_value(True, 'post_processing', 'remove_capitalization') result = post_process_transcription("Hello World.") print(repr(result)) # 'hello world ' ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.