From 028e3b2240555d49ae77c6a8a090bc023f32a2e2 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Wed, 22 Apr 2026 19:32:40 +0200 Subject: [PATCH] fix: Voice-Auswahl funktioniert endlich + Diagnostic setzt alle Apps zurueck MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit XTTS-Bridge: im daswer123 local-Mode erwartet der Server speaker_wav als Basename (z.B. "Maia"), nicht als Pfad. Wir haben bisher "/voices/Maia.wav" geschickt, was der Server stumm verwirft und Default nimmt. Jetzt: speaker name pur senden + Warnlog wenn File fehlt. App: ChatScreen + SettingsScreen horchen auf type "config" vom RVS — wenn in Diagnostic die globale XTTS-Voice gewechselt wird, werden alle Apps auf den neuen Wert zurueckgesetzt (wie vom User gewuenscht). Lokale App-Wahl bleibt sonst intakt und gewinnt pro Request. Co-Authored-By: Claude Opus 4.7 (1M context) --- android/src/screens/ChatScreen.tsx | 9 +++++++++ android/src/screens/SettingsScreen.tsx | 7 +++++++ xtts/bridge.js | 18 ++++++++++++++---- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/android/src/screens/ChatScreen.tsx b/android/src/screens/ChatScreen.tsx index 9bf1240..72f7689 100644 --- a/android/src/screens/ChatScreen.tsx +++ b/android/src/screens/ChatScreen.tsx @@ -325,6 +325,15 @@ const ChatScreen: React.FC = () => { const tool = (message.payload.tool as string) || ''; setAgentActivity({ activity, tool }); } + + // Voice-Config aus Diagnostic — setzt die lokale App-Stimme auf den + // gerade in Diagnostic gewaehlten Wert zurueck. User-Wahl in der App + // wird dadurch ueberschrieben. + if (message.type === ('config' as any)) { + const newVoice = ((message.payload as any).xttsVoice as string) ?? ''; + localXttsVoiceRef.current = newVoice; + AsyncStorage.setItem('aria_xtts_voice', newVoice); + } }); const unsubState = rvs.onStateChange((state) => { diff --git a/android/src/screens/SettingsScreen.tsx b/android/src/screens/SettingsScreen.tsx index b55937e..26b558c 100644 --- a/android/src/screens/SettingsScreen.tsx +++ b/android/src/screens/SettingsScreen.tsx @@ -265,6 +265,13 @@ const SettingsScreen: React.FC = () => { } rvs.send('xtts_list_voices' as any, {}); } + + // Diagnostic-Voice-Wechsel → lokale App-Stimme auf den neuen Default zuruecksetzen + if (message.type === ('config' as any)) { + const newVoice = ((message.payload as any).xttsVoice as string) ?? ''; + setXttsVoice(newVoice); + AsyncStorage.setItem('aria_xtts_voice', newVoice); + } }); return () => { diff --git a/xtts/bridge.js b/xtts/bridge.js index edfc698..c1ff8fa 100644 --- a/xtts/bridge.js +++ b/xtts/bridge.js @@ -151,8 +151,18 @@ async function _runTTSRequest(payload) { log(`TTS-Request (streaming): "${cleanText.slice(0, 80)}..." (${cleanText.length} chars, voice: ${voice || "default"})`); try { - const voiceSample = voice ? path.join(VOICES_DIR, `${voice}.wav`) : null; - const hasCustomVoice = voiceSample && fs.existsSync(voiceSample); + // Im local-Mode erwartet daswer123 XTTS speaker_wav als Basename (ohne .wav, + // ohne Pfad) — der Server prefixt EXAMPLE_FOLDER selbst. Wir checken hier + // nur das physische File ab um Warnungen zu loggen; runter ans API geht + // nur der Name. + const voiceFilePath = voice ? path.join(VOICES_DIR, `${voice}.wav`) : null; + const hasCustomVoice = voiceFilePath && fs.existsSync(voiceFilePath); + const speakerName = hasCustomVoice ? voice : ""; + if (voice && !hasCustomVoice) { + log(`WARNUNG: Voice "${voice}" angefordert, aber ${voiceFilePath} existiert nicht — nehme Default`); + } else if (hasCustomVoice) { + log(`Voice "${voice}" verwendet (speaker_wav="${speakerName}")`); + } let chunkIndex = 0; let pcmMeta = null; @@ -190,7 +200,7 @@ async function _runTTSRequest(payload) { await streamXTTSAsPCM( cleanText, language || "de", - hasCustomVoice ? voiceSample : null, + speakerName, onChunk, ); } catch (streamErr) { @@ -198,7 +208,7 @@ async function _runTTSRequest(payload) { await streamXTTSBatch( cleanText, language || "de", - hasCustomVoice ? voiceSample : null, + speakerName, onChunk, ); }