+ {[0.5, 0.75, 1.0, 1.25, 1.5, 2.0].map(speed => (
+ {
+ setSpeedThorsten(speed);
+ AsyncStorage.setItem('aria_speed_thorsten', String(speed));
+ rvs.send('config' as any, { speedThorsten: speed });
+ }}
+ style={{
+ paddingHorizontal: 10, paddingVertical: 6, borderRadius: 6,
+ backgroundColor: speedThorsten === speed ? '#0096FF' : '#1E1E2E',
+ }}
+ >
+
{speed}x
diff --git a/bridge/aria_bridge.py b/bridge/aria_bridge.py
index 62b17de..e16ee80 100644
--- a/bridge/aria_bridge.py
+++ b/bridge/aria_bridge.py
@@ -132,7 +132,7 @@ class VoiceEngine:
self.voices: dict[str, PiperVoice] = {}
self.default_voice = "ramona"
self.highlight_voice = "thorsten"
- self.speech_speed = 1.0 # 0.5 = langsam, 1.0 = normal, 2.0 = schnell
+ self.speech_speed = {"ramona": 1.0, "thorsten": 1.0}
def initialize(self) -> None:
"""Laedt die Piper-Stimmen aus dem Voices-Verzeichnis."""
@@ -218,7 +218,8 @@ class VoiceEngine:
continue
with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp:
tmp_path = tmp.name
- syn_config = SynthesisConfig(length_scale=1.0 / max(0.3, self.speech_speed))
+ speed = self.speech_speed.get(voice_name, 1.0)
+ syn_config = SynthesisConfig(length_scale=1.0 / max(0.3, speed))
with wave.open(tmp_path, "wb") as wav_file:
voice.synthesize_wav(sentence, wav_file, syn_config=syn_config)
with wave.open(tmp_path, "rb") as wav_file:
@@ -497,7 +498,10 @@ class ARIABridge:
vc = json.load(f)
self.voice_engine.default_voice = vc.get("defaultVoice", "ramona")
self.voice_engine.highlight_voice = vc.get("highlightVoice", "thorsten")
- self.voice_engine.speech_speed = vc.get("speechSpeed", 1.0)
+ self.voice_engine.speech_speed = {
+ "ramona": vc.get("speedRamona", 1.0),
+ "thorsten": vc.get("speedThorsten", 1.0),
+ }
self.tts_enabled = vc.get("ttsEnabled", True)
logger.info("Voice-Config geladen: %s", vc)
except Exception as e:
@@ -1028,9 +1032,13 @@ class ARIABridge:
self.tts_enabled = bool(payload["ttsEnabled"])
logger.info("[rvs] TTS %s", "aktiviert" if self.tts_enabled else "deaktiviert")
changed = True
- if "speechSpeed" in payload:
- self.voice_engine.speech_speed = max(0.3, min(2.0, float(payload["speechSpeed"])))
- logger.info("[rvs] Sprechgeschwindigkeit: %.1f", self.voice_engine.speech_speed)
+ if "speedRamona" in payload:
+ self.voice_engine.speech_speed["ramona"] = max(0.3, min(2.0, float(payload["speedRamona"])))
+ logger.info("[rvs] Speed Ramona: %.1f", self.voice_engine.speech_speed["ramona"])
+ changed = True
+ if "speedThorsten" in payload:
+ self.voice_engine.speech_speed["thorsten"] = max(0.3, min(2.0, float(payload["speedThorsten"])))
+ logger.info("[rvs] Speed Thorsten: %.1f", self.voice_engine.speech_speed["thorsten"])
changed = True
# Persistent speichern in Shared Volume
if changed:
@@ -1040,7 +1048,8 @@ class ARIABridge:
"defaultVoice": self.voice_engine.default_voice,
"highlightVoice": self.voice_engine.highlight_voice,
"ttsEnabled": getattr(self, "tts_enabled", True),
- "speechSpeed": self.voice_engine.speech_speed,
+ "speedRamona": self.voice_engine.speech_speed.get("ramona", 1.0),
+ "speedThorsten": self.voice_engine.speech_speed.get("thorsten", 1.0),
}
with open("/shared/config/voice_config.json", "w") as f:
json.dump(config_data, f, indent=2)
diff --git a/diagnostic/index.html b/diagnostic/index.html
index e97a1e0..e457763 100644
--- a/diagnostic/index.html
+++ b/diagnostic/index.html
@@ -419,12 +419,23 @@
-
+
+
+
+ 0.5x
+
+ 2.0x
+
+
+
0.5x
-
2.0x
@@ -657,9 +668,12 @@
document.getElementById('diag-default-voice').value = msg.defaultVoice || 'ramona';
document.getElementById('diag-highlight-voice').value = msg.highlightVoice || 'thorsten';
document.getElementById('diag-tts-enabled').checked = msg.ttsEnabled !== false;
- const speed = msg.speechSpeed || 1.0;
- document.getElementById('diag-speech-speed').value = speed;
- document.getElementById('speed-label').textContent = speed + 'x';
+ const sr = msg.speedRamona || 1.0;
+ const st = msg.speedThorsten || 1.0;
+ document.getElementById('diag-speed-ramona').value = sr;
+ document.getElementById('speed-ramona-label').textContent = sr + 'x';
+ document.getElementById('diag-speed-thorsten').value = st;
+ document.getElementById('speed-thorsten-label').textContent = st + 'x';
return;
}
@@ -1157,8 +1171,9 @@
const defaultVoice = document.getElementById('diag-default-voice').value;
const highlightVoice = document.getElementById('diag-highlight-voice').value;
const ttsEnabled = document.getElementById('diag-tts-enabled').checked;
- const speechSpeed = parseFloat(document.getElementById('diag-speech-speed').value);
- send({ action: 'send_voice_config', defaultVoice, highlightVoice, ttsEnabled, speechSpeed });
+ const speedRamona = parseFloat(document.getElementById('diag-speed-ramona').value);
+ const speedThorsten = parseFloat(document.getElementById('diag-speed-thorsten').value);
+ send({ action: 'send_voice_config', defaultVoice, highlightVoice, ttsEnabled, speedRamona, speedThorsten });
}
// ── Highlight-Trigger ────────────────────────
diff --git a/diagnostic/server.js b/diagnostic/server.js
index e970f93..9f18e47 100644
--- a/diagnostic/server.js
+++ b/diagnostic/server.js
@@ -1135,7 +1135,8 @@ wss.on("connection", (ws) => {
defaultVoice: msg.defaultVoice || "ramona",
highlightVoice: msg.highlightVoice || "thorsten",
ttsEnabled: msg.ttsEnabled !== false,
- speechSpeed: msg.speechSpeed || 1.0,
+ speedRamona: msg.speedRamona || 1.0,
+ speedThorsten: msg.speedThorsten || 1.0,
};
try {
fs.mkdirSync("/shared/config", { recursive: true });