chore: Commit all pending local changes

This commit is contained in:
mARTin-B78 2026-06-22 14:59:37 +02:00
parent 3f1e82ef81
commit f82a2cfb6a
9 changed files with 53 additions and 22 deletions

View File

@ -18,6 +18,7 @@ services:
- ${VOICE_HOST_DIR:-/home/sparky/Media/_Sounds/TTS_Voices}:/voices:rw
- ./config:/home/app/.config/tts-voice-creator:rw # settings, presets, routes
- ./logs:/logs:rw # application logs
- /home/sparky/Docker/tts-dgx-spark-faster-qwen3-tts/config:/tts-config:rw
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./static:/app/static:ro
- ./server.py:/app/server.py:ro
@ -31,7 +32,8 @@ services:
- VOICES_DIR=/voices
- OUTPUT_DIR=/voices/active_voices
# Containers that load WAV files and need a restart after voice changes
- TTS_CONTAINER_NAMES=faster-qwen3-tts-voiceclone,faster-qwen3-tts-streaming
- TTS_CONTAINER_NAME=tts-faster-qwen3-tts-voiceclone
- TTS_CONTAINER_NAMES=tts-faster-qwen3-tts-voiceclone,tts-faster-qwen3-tts-streaming
- VOICE_DESIGN_MODEL=Qwen3-TTS-12Hz-1.7B-VoiceDesign
extra_hosts:

View File

@ -0,0 +1 @@
Die 3.567 neuen High-End Geräte für das Server-Update benötigen eine außergewöhnlich starke Kühlung und regelmäßige Maßnahmen, um die Performance bei großer Last zu gewährleisten. - The system administrator successfully configured the customized Docker stacks and benchmarked the inference engines at exactly 8:45 AM. - Notiere dir an Midsummer 21.06. um 14 Uhr - Es ist reine Zeitverschwendung, etwas Mittelmäßiges zu tun! Schöne Grüße! — Madonna - Träume beginnt mit einem positiven Mindset.

View File

@ -33,6 +33,7 @@ services:
- /home/sparky/Media/_Sounds/TTS_Voices:/voices:rw
- /home/sparky/Docker/tts-voice-creator-clone-and-design-2/config:/home/app/.config/tts-voice-creator:rw
- /home/sparky/Docker/tts-voice-creator-clone-and-design-2/logs:/logs:rw
- /home/sparky/Docker/tts-dgx-spark-faster-qwen3-tts/config:/tts-config:rw
- /var/run/docker.sock:/var/run/docker.sock:ro
# ── Hot-reload mounts (changes apply on container recreate, not restart) ──
- /home/sparky/Docker/tts-voice-creator-clone-and-design-2/server.py:/app/server.py:ro
@ -47,8 +48,8 @@ services:
- VOICES_DIR=/voices
- OUTPUT_DIR=/voices/active_voices
- TTS_STREAM_URL=http://host.docker.internal:8023
- TTS_CONTAINER_NAME=faster-qwen3-tts-voiceclone
- TTS_CONTAINER_NAMES=faster-qwen3-tts-voiceclone,faster-qwen3-tts-streaming
- TTS_CONTAINER_NAME=tts-faster-qwen3-tts-voiceclone
- TTS_CONTAINER_NAMES=tts-faster-qwen3-tts-voiceclone,tts-faster-qwen3-tts-streaming
- VOICE_DESIGN_MODEL=Qwen3-TTS-12Hz-1.7B-VoiceDesign
extra_hosts:

View File

@ -19,10 +19,10 @@ _LOCAL_CONTAINER_DEFS: list[dict] = [
{"name": "ollama", "label": "Ollama", "role": "llm", "port": 11434, "stack": "dgx-spark_lite-llm_llama-swap_vllm_llama-cpp_ollama", "image": "ollama/ollama", "repo": "https://ollama.com", "description": "Local LLM runtime. The app uses its OpenAI-compatible /v1 endpoint."},
{"name": "llama-swap", "label": "llama-swap", "role": "llm", "port": 28080, "stack": "dgx-spark_lite-llm_llama-swap_vllm_llama-cpp_ollama", "image": "ghcr.io/mostlygeek/llama-swap:cuda", "repo": "https://github.com/mostlygeek/llama-swap", "description": "Model swapping proxy for local LLMs. Useful as the default Rehearser LLM endpoint."},
{"name": "llama-qwen35-4b", "label": "Qwen3.5 4B LLM", "role": "llm", "port": 19001, "stack": "dgx-spark_lite-llm_llama-swap_vllm_llama-cpp_ollama", "image": "local", "repo": "", "description": "Dedicated Qwen LLM container. Use if it exposes an OpenAI-compatible /v1 API."},
{"name": "faster-qwen3-tts-voiceclone", "label": "Qwen3 TTS · Voice Clone", "role": "tts", "port": 8020, "stack": "faster-qwen3-tts-dgx-spark", "image": "martinb78/faster-qwen3-tts-dgx-spark:v4", "repo": "https://github.com/mARTin-B78/dgx-spark-faster-qwen3-tts", "description": "WAV voice cloning. Scans active_voices at startup; restart after adding or editing voices."},
{"name": "faster-qwen3-tts-voicedesign", "label": "Qwen3 TTS · Voice Design", "role": "tts", "port": 8021, "stack": "faster-qwen3-tts-dgx-spark", "image": "martinb78/faster-qwen3-tts-dgx-spark:v4", "repo": "https://github.com/mARTin-B78/dgx-spark-faster-qwen3-tts", "description": "Instruction-based voice design. Best Qwen path for tone, style, and character prompts."},
{"name": "faster-qwen3-tts-customvoice", "label": "Qwen3 TTS · Custom Voice", "role": "tts", "port": 8022, "stack": "faster-qwen3-tts-dgx-spark", "image": "martinb78/faster-qwen3-tts-dgx-spark:v4", "repo": "https://github.com/mARTin-B78/dgx-spark-faster-qwen3-tts", "description": "CustomVoice speakers with per-request instruct overrides for tone/style."},
{"name": "faster-qwen3-tts-streaming", "label": "Qwen3 TTS · Streaming", "role": "tts", "port": 8023, "stack": "faster-qwen3-tts-dgx-spark", "image": "martinb78/faster-qwen3-tts-dgx-spark:streaming", "repo": "https://github.com/mARTin-B78/dgx-spark-faster-qwen3-tts", "description": "Low-latency progressive WAV streaming for voice clone voices."},
{"name": "tts-faster-qwen3-tts-voiceclone", "label": "Qwen3 TTS · Voice Clone", "role": "tts", "port": 8020, "stack": "faster-qwen3-tts-dgx-spark", "image": "martinb78/faster-qwen3-tts-dgx-spark:v4", "repo": "https://github.com/mARTin-B78/dgx-spark-faster-qwen3-tts", "description": "WAV voice cloning. Scans active_voices at startup; restart after adding or editing voices."},
{"name": "tts-faster-qwen3-tts-voicedesign", "label": "Qwen3 TTS · Voice Design", "role": "tts", "port": 8021, "stack": "faster-qwen3-tts-dgx-spark", "image": "martinb78/faster-qwen3-tts-dgx-spark:v4", "repo": "https://github.com/mARTin-B78/dgx-spark-faster-qwen3-tts", "description": "Instruction-based voice design. Best Qwen path for tone, style, and character prompts."},
{"name": "tts-faster-qwen3-tts-customvoice", "label": "Qwen3 TTS · Custom Voice", "role": "tts", "port": 8022, "stack": "faster-qwen3-tts-dgx-spark", "image": "martinb78/faster-qwen3-tts-dgx-spark:v4", "repo": "https://github.com/mARTin-B78/dgx-spark-faster-qwen3-tts", "description": "CustomVoice speakers with per-request instruct overrides for tone/style."},
{"name": "tts-faster-qwen3-tts-streaming", "label": "Qwen3 TTS · Streaming", "role": "tts", "port": 8023, "stack": "faster-qwen3-tts-dgx-spark", "image": "martinb78/faster-qwen3-tts-dgx-spark:streaming", "repo": "https://github.com/mARTin-B78/dgx-spark-faster-qwen3-tts", "description": "Low-latency progressive WAV streaming for voice clone voices."},
{"name": "faster-whisper", "label": "faster-whisper", "role": "stt", "port": 8010, "stack": "faster-whisper-dgx-spark", "image": "local", "repo": "https://github.com/SYSTRAN/faster-whisper", "description": "Fast local Whisper transcription endpoint."},
{"name": "fish-speech-api", "label": "Fish-Speech API", "role": "tts", "port": 38080, "stack": "fish-speech-dgx-spark", "image": "local", "repo": "https://github.com/fishaudio/fish-speech", "description": "Tone-aware cloning backend. Recommended for Rehearser character voices when you need both identity and emotion."},
{"name": "nemotron-asr-streaming", "label": "Nemotron ASR Streaming", "role": "stt", "port": 8006, "stack": "nemotron-asr-streaming", "image": "local", "repo": "https://github.com/pipecat-ai/nemotron-january-2026", "description": "Streaming ASR service. Use as a custom STT endpoint if it exposes OpenAI transcription or /transcribe."},

View File

@ -641,9 +641,23 @@ async def rename_voice(request: Request):
if backup and backup.exists():
if backup.resolve() != new_backup.resolve():
backup.rename(new_backup)
new_meta = _load_meta(new_audio)
# Also rename TTS config assets if mounted
tts_config = Path("/tts-config")
if tts_config.exists():
old_pt = tts_config / "speakers" / f"{old_id}.pt"
if old_pt.exists():
old_pt.rename(tts_config / "speakers" / f"{new_id}.pt")
old_seeds = tts_config / "seed_samples" / old_id
if old_seeds.exists() and old_seeds.is_dir():
old_seeds.rename(tts_config / "seed_samples" / new_id)
new_meta = _load_meta(new_audio)
if backup and backup.exists():
new_meta["original_backup"] = str(new_backup)
_save_meta(new_audio, new_meta)
new_meta["needs_tts_restart"] = True
_save_meta(new_audio, new_meta)
return {"new_id": new_id, "path": str(new_audio), "file_type": new_audio.suffix.lower().lstrip(".")}

View File

@ -201,10 +201,10 @@ function saveCustomEngineCards(cards) {
// Settings key per docker container name; role fallback for custom cards
const DC_USE_MAP = {
'faster-qwen3-tts-voiceclone': { settingKey: 'tts_url', label: 'Use as TTS' },
'faster-qwen3-tts-voicedesign': { settingKey: 'voice_design_url', label: 'Use as Voice Design' },
'faster-qwen3-tts-customvoice': { settingKey: 'customvoice_url', label: 'Use as CustomVoice' },
'faster-qwen3-tts-streaming': { settingKey: 'tts_stream_url', label: 'Use as Streaming TTS' },
'tts-faster-qwen3-tts-voiceclone': { settingKey: 'tts_url', label: 'Use as TTS' },
'tts-faster-qwen3-tts-voicedesign': { settingKey: 'voice_design_url', label: 'Use as Voice Design' },
'tts-faster-qwen3-tts-customvoice': { settingKey: 'customvoice_url', label: 'Use as CustomVoice' },
'tts-faster-qwen3-tts-streaming': { settingKey: 'tts_stream_url', label: 'Use as Streaming TTS' },
'faster-whisper': { settingKey: 'faster_whisper_url', label: 'Use as STT' },
'fish-speech-api': { settingKey: 'fishspeech_url', label: 'Use as Fish-Speech' },
'nemotron-asr-streaming': { settingKey: 'faster_whisper_url', label: 'Use as STT' },
@ -333,10 +333,10 @@ function renderLocalContainers(containers) {
const ROLE_LABEL = { tts: 'TTS', stt: 'STT', 'stt+tts': 'STT · TTS', llm: 'LLM' };
const DC_ICONS = {
'faster-qwen3-tts-voiceclone': '<span class="mdi mdi-speaker-outline"></span>',
'faster-qwen3-tts-voicedesign': '<span class="mdi mdi-auto-fix"></span>',
'faster-qwen3-tts-customvoice': '🎭',
'faster-qwen3-tts-streaming': '<span class="mdi mdi-lightning-bolt"></span>',
'tts-faster-qwen3-tts-voiceclone': '<span class="mdi mdi-speaker-outline"></span>',
'tts-faster-qwen3-tts-voicedesign': '<span class="mdi mdi-auto-fix"></span>',
'tts-faster-qwen3-tts-customvoice': '🎭',
'tts-faster-qwen3-tts-streaming': '<span class="mdi mdi-lightning-bolt"></span>',
'parakeet-asr': '🦜',
'magpie-tts': '🐦',
'parakeet-rnnt-nim': '🦜',
@ -357,10 +357,10 @@ function renderLocalContainers(containers) {
const _q = (v) => `<span class="mdi mdi-star-outline"></span>`;
const _m = (v) => `<span class="mdi mdi-memory"></span>`;
const DC_METRICS = {
'faster-qwen3-tts-voiceclone': [[_t(),'~0.3× GPU'],[_l(),'13 s'],[_q(),'Premium clone'],[_m(),'68 GB VRAM']],
'faster-qwen3-tts-voicedesign': [[_t(),'~0.4× GPU'],[_l(),'13 s'],[_q(),'Premium'], [_m(),'68 GB VRAM']],
'faster-qwen3-tts-customvoice': [[_t(),'~0.3× GPU'],[_l(),'13 s'],[_q(),'Premium'], [_m(),'68 GB VRAM']],
'faster-qwen3-tts-streaming': [[_t(),'~0.1× GPU'],[_l(),'0.51 s'],[_q(),'Premium'], [_m(),'68 GB VRAM']],
'tts-faster-qwen3-tts-voiceclone': [[_t(),'~0.3× GPU'],[_l(),'13 s'],[_q(),'Premium clone'],[_m(),'68 GB VRAM']],
'tts-faster-qwen3-tts-voicedesign': [[_t(),'~0.4× GPU'],[_l(),'13 s'],[_q(),'Premium'], [_m(),'68 GB VRAM']],
'tts-faster-qwen3-tts-customvoice': [[_t(),'~0.3× GPU'],[_l(),'13 s'],[_q(),'Premium'], [_m(),'68 GB VRAM']],
'tts-faster-qwen3-tts-streaming': [[_t(),'~0.1× GPU'],[_l(),'0.51 s'],[_q(),'Premium'], [_m(),'68 GB VRAM']],
'magpie-tts': [[_t(),'~0.05× GPU'],[_l(),'0.30.8 s'],[_q(),'High'], [_m(),'46 GB VRAM']],
'parakeet-asr': [[_t(),'~200× RT GPU'],[_l(),'<0.3 s'],[_q(),'Parakeet-TDT'],[_m(),'2 GB VRAM']],
'parakeet-rnnt-nim': [[_t(),'~200× RT GPU'],[_l(),'<0.3 s'],[_q(),'Parakeet-1B'], [_m(),'2 GB VRAM']],

View File

@ -12,6 +12,9 @@ const SEED_FINDER_TEXT_EN = SEED_FINDER_TEXT_DE;
const SEED_FINDER_TEXT_MIXED = SEED_FINDER_TEXT_DE;
function _seedFinderDefaultText(voiceId) {
if (window._appSettings && window._appSettings.seed_finder_text) {
return window._appSettings.seed_finder_text;
}
const lc = (voiceId || '').toLowerCase();
if (lc.startsWith('de_')) return SEED_FINDER_TEXT_MIXED;
if (lc.startsWith('en_') || lc.startsWith('gb_')) return SEED_FINDER_TEXT_EN;

View File

@ -342,7 +342,8 @@ const SETTINGS_FIELD_HELP = {
's-output-dir': ['Active voices directory', 'Container path where new cloned or exported voices are saved. Usually /voices/active_voices.'],
's-tts-key': ['TTS API key', 'Optional. For local OpenAI-compatible servers, sk-local or empty usually works.'],
's-vd-key': ['Voice Design API key', 'Optional. Use only if your Voice Design backend requires Authorization.'],
's-whisper-key': ['Whisper API key', 'Optional. Needed for cloud STT, usually empty for local Whisper-compatible containers.']
's-whisper-key': ['Whisper API key', 'Optional. Needed for cloud STT, usually empty for local Whisper-compatible containers.'],
's-seed-finder-text': ['Seed Finder text', 'Custom test sentence used when opening the Seed Finder. Leave empty to use language defaults.']
};
@ -459,6 +460,8 @@ async function loadSettings() {
$('s-vd-key').value = s.voice_design_api_key || '';
$('s-voices-scan-dir').value = s.voices_scan_dir || '';
$('s-output-dir').value = s.output_dir || '';
const seedTextEl = $('s-seed-finder-text');
if (seedTextEl) seedTextEl.value = s.seed_finder_text || '';
const themeEl = $('s-theme-select');
if (themeEl) themeEl.value = document.documentElement.dataset.theme || 'dark';
// Captures settings
@ -566,6 +569,7 @@ document.addEventListener('click', async e => { if (!e.target.closest('.s-save-b
refine_corrections: $('s-refine-corrections')?.checked ?? true,
refine_punctuation: $('s-refine-punctuation')?.checked ?? true,
captures_default_voice: $('s-captures-default-voice')?.value || '',
seed_finder_text: $('s-seed-finder-text')?.value || '',
}) });
_appSettings.tts_stream_url = $('s-tts-stream-url').value;
_appSettings.customvoice_url = $('s-customvoice-url').value;
@ -579,6 +583,7 @@ document.addEventListener('click', async e => { if (!e.target.closest('.s-save-b
_appSettings.vibevoice_url = $('s-vibevoice-url').value;
_appSettings.xtts_url = $('s-xtts-url')?.value || '';
_appSettings.tts_stream_mode = $('s-tts-stream-mode').value;
_appSettings.seed_finder_text = $('s-seed-finder-text')?.value || '';
_ttsStreamHealth = null;
await refreshTtsBackendAvailability($('tts-backend-select')?.value || '');
markSettingsSeen();

View File

@ -24,6 +24,11 @@
</select>
<span class="s-hint">Switch between light and dark interface. Saved instantly.</span>
</div>
<div class="s-field" style="grid-column: 1 / -1">
<label>Default Seed Finder text</label>
<textarea id="s-seed-finder-text" placeholder="Leave empty for language-specific defaults..." style="min-height:60px; font-family:inherit; resize:vertical;"></textarea>
<span class="s-hint">Custom test sentence used when opening the Seed Finder.</span>
</div>
</div>
</div>
</div>