diff --git a/android/android/app/src/main/java/com/ariacockpit/PcmStreamPlayerModule.kt b/android/android/app/src/main/java/com/ariacockpit/PcmStreamPlayerModule.kt index ab8d8b1..ee84268 100644 --- a/android/android/app/src/main/java/com/ariacockpit/PcmStreamPlayerModule.kt +++ b/android/android/app/src/main/java/com/ariacockpit/PcmStreamPlayerModule.kt @@ -50,8 +50,10 @@ class PcmStreamPlayerModule(reactContext: ReactApplicationContext) : ReactContex val channelConfig = if (channels == 2) AudioFormat.CHANNEL_OUT_STEREO else AudioFormat.CHANNEL_OUT_MONO val encoding = AudioFormat.ENCODING_PCM_16BIT val minBuf = AudioTrack.getMinBufferSize(sampleRate, channelConfig, encoding) - // Etwas grosszuegiger Buffer: 8x MinSize (ca. 200-400ms bei 24kHz) — glatt auch bei kleinen Netzwerk-Aussetzern - val bufferSize = (minBuf * 8).coerceAtLeast(32 * 1024) + // Grosszuegiger Buffer: 32x MinSize — tolerant gegen Netzwerk-Jitter und + // bursty XTTS-Delivery (Render dauert 1-3s, dann kommen alle Samples + // auf einmal). Bei 24kHz mono s16 entspricht 128KB ca. 2.7 Sekunden. + val bufferSize = (minBuf * 32).coerceAtLeast(128 * 1024) val newTrack = AudioTrack.Builder() .setAudioAttributes( diff --git a/xtts/bridge.js b/xtts/bridge.js index f05a133..3ec7655 100644 --- a/xtts/bridge.js +++ b/xtts/bridge.js @@ -95,7 +95,20 @@ function connectRVS(forcePlain) { // ── TTS Request Handler ───────────────────────────── -async function handleTTSRequest(payload) { +// ── TTS-Queue ────────────────────────────────────── +// XTTS verarbeitet Requests sequenziell, damit Streams sich nicht ueberlappen. +// Ohne Queue wuerden parallele Requests parallel streamen → App bekommt +// interleaved PCM-Chunks aus zwei Rendern → klingt wie Chaos. +let ttsQueue = Promise.resolve(); + +function handleTTSRequest(payload) { + ttsQueue = ttsQueue.then(() => _runTTSRequest(payload)).catch(err => { + log(`TTS-Queue Fehler: ${err.message}`); + }); + return ttsQueue; +} + +async function _runTTSRequest(payload) { const { text, voice, requestId, language, messageId } = payload; if (!text) return;