From b91ddc5bdf8c39a681afb2210c0d8dbf32172fd1 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Sun, 10 May 2026 14:45:05 +0200 Subject: [PATCH] =?UTF-8?q?fix(audio):=20AudioTrack-Start-Threshold=20auf?= =?UTF-8?q?=20100ms=20=E2=80=94=20kurze=20TTS=20startet=20jetzt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ENDLICH die Wurzel: AudioTrack hat seit API 31 setStartThresholdInFrames(), default ist bufferSize/2. Bei 4s-Buffer = 2s Threshold — Track wartet bis 2s im Buffer sind, sonst startet play() nie wirklich (pos bleibt 0). Bei 3 Worten (~1.4s) kommt's nie ueber die Schwelle. Threshold runter auf 100ms (2400 Frames @ 24kHz) — Track laeuft sofort mit erstem Chunk an. Erklaert auch warum genau ab 9 Worten (~3s+) der Pre-Roll-Pfad lief: dann wurde die 2s-Schwelle ueberschritten. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../com/ariacockpit/PcmStreamPlayerModule.kt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) 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 e970a43..fedc35d 100644 --- a/android/android/app/src/main/java/com/ariacockpit/PcmStreamPlayerModule.kt +++ b/android/android/app/src/main/java/com/ariacockpit/PcmStreamPlayerModule.kt @@ -4,6 +4,7 @@ import android.media.AudioAttributes import android.media.AudioFormat import android.media.AudioManager import android.media.AudioTrack +import android.os.Build import android.util.Base64 import android.util.Log import com.facebook.react.bridge.Arguments @@ -107,7 +108,20 @@ class PcmStreamPlayerModule(reactContext: ReactApplicationContext) : ReactContex .setTransferMode(AudioTrack.MODE_STREAM) .build() - // AudioTrack erstellen — play() wird erst aufgerufen wenn Pre-Roll erreicht. + // Start-Threshold runterdrehen: Default ist bufferSize/2 (= 2s bei 4s + // Buffer). AudioTrack startet sonst nicht bevor 2s im Puffer sind — + // bei kurzen TTS-Antworten (3 Worte ~ 1.4s) bleibt pos auf 0 stehen. + // 0.1s reicht damit AudioTrack sofort mit dem ersten Chunk anlaeuft. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + try { + val startFrames = (sampleRate / 10).coerceAtLeast(1) // 100ms + newTrack.setStartThresholdInFrames(startFrames) + Log.i(TAG, "Start-Threshold gesetzt: ${startFrames} frames (~100ms)") + } catch (e: Exception) { + Log.w(TAG, "setStartThresholdInFrames failed: ${e.message}") + } + } + track = newTrack queue.clear() writerShouldStop = false