Initial commit of WhisperVoice

This commit is contained in:
Your Name
2026-01-24 17:03:52 +02:00
commit 9ff0e8d108
118 changed files with 6102 additions and 0 deletions

117
src/core/config.py Normal file
View File

@@ -0,0 +1,117 @@
"""
Configuration Manager Module.
=============================
Singleton class to manage loading and saving application settings to a JSON file.
Ensures robustness by merging with defaults and handling file paths correctly.
"""
import json
import logging
from pathlib import Path
from typing import Any, Dict
from src.core.paths import get_base_path
# Default Configuration
DEFAULT_SETTINGS = {
"hotkey": "f8",
"model_size": "small",
"input_device": None, # Device ID (int) or Name (str), None = Default
"save_recordings": False, # Save .wav files for debugging
"silence_threshold": 0.02, # Amplitude threshold (0.0 - 1.0)
"silence_duration": 1.0, # Seconds of silence to trigger auto-submit
"visualizer_style": "line", # 'bar' or 'line'
"opacity": 1.0, # Window opacity (0.1 - 1.0)
"ui_scale": 1.0, # Global UI Scale (0.75 - 1.5)
"always_on_top": True,
"run_on_startup": False, # (Placeholder)
# Window Position
"overlay_position": "Bottom Center",
"overlay_offset_x": 0,
"overlay_offset_y": 0,
# Input
"input_method": "Clipboard Paste", # "Clipboard Paste" or "Simulate Typing"
"typing_speed": 100, # CPM (Chars Per Minute) if typing
# AI - Advanced
"language": "auto", # "auto" or ISO code
"compute_device": "auto", # "auto", "cuda", "cpu"
"compute_type": "int8", # "int8", "float16", "float32"
"beam_size": 5,
"best_of": 5,
"vad_filter": True,
"no_repeat_ngram_size": 0,
"condition_on_previous_text": True
}
class ConfigManager:
"""
Singleton Configuration Manager.
"""
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(ConfigManager, cls).__new__(cls)
cls._instance._init()
return cls._instance
def _init(self):
"""Initialize the config manager (called only once)."""
self.base_path = get_base_path()
self.config_file = self.base_path / "settings.json"
self.data = DEFAULT_SETTINGS.copy()
self.load()
def load(self):
"""Load settings from JSON file, merging with defaults."""
if self.config_file.exists():
try:
with open(self.config_file, 'r', encoding='utf-8') as f:
loaded = json.load(f)
# Merge loaded data into defaults (preserves new default keys)
for key, value in loaded.items():
if key in DEFAULT_SETTINGS:
self.data[key] = value
logging.info(f"Settings loaded from {self.config_file}")
except Exception as e:
logging.error(f"Failed to load settings: {e}")
else:
logging.info("No settings file found. Using defaults.")
self.save()
def save(self):
"""Save current settings to JSON file."""
try:
with open(self.config_file, 'w', encoding='utf-8') as f:
json.dump(self.data, f, indent=4)
logging.info("Settings saved.")
except Exception as e:
logging.error(f"Failed to save settings: {e}")
def get(self, key: str) -> Any:
"""Get a setting value."""
return self.data.get(key, DEFAULT_SETTINGS.get(key))
def set(self, key: str, value: Any):
"""Set a setting value and save."""
if self.data.get(key) != value:
self.data[key] = value
self.save()
def set_bulk(self, updates: Dict[str, Any]):
"""Update multiple keys and save once."""
changed = False
for k, v in updates.items():
if self.data.get(k) != v:
self.data[k] = v
changed = True
if changed:
self.save()