Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0350dd33c8 | ||
|
|
7b956c6606 | ||
|
|
36f04f83ff |
@@ -79,8 +79,8 @@ android {
|
||||
applicationId "com.ariacockpit"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 20304
|
||||
versionName "0.2.3.4"
|
||||
versionCode 20305
|
||||
versionName "0.2.3.5"
|
||||
// Fallback fuer Libraries mit Product Flavors
|
||||
missingDimensionStrategy 'react-native-camera', 'general'
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "aria-cockpit",
|
||||
"version": "0.2.3.4",
|
||||
"version": "0.2.3.5",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"android": "react-native run-android",
|
||||
|
||||
@@ -152,12 +152,12 @@ export const CONV_WINDOW_MAX_SEC = 20.0;
|
||||
export const CONV_WINDOW_STORAGE_KEY = 'aria_conv_window_sec';
|
||||
|
||||
// STT-Endpoint (ms Stille bis "fertig gesprochen"). Zu kurz = schneidet mitten
|
||||
// im Satz ab, besonders im Auto wo man mit Pausen spricht (Reproduktion: die
|
||||
// 11.8s-Frage wurde bei "…ohne dass ein" gekappt). 1500 war zu aggressiv;
|
||||
// 2400 default, im Auto ggf. hoeher. Konfigurierbar in den Settings.
|
||||
// im Satz ab, besonders im Auto oder wenn man zum Nachdenken pausiert. 1500 war
|
||||
// zu aggressiv; 2400 default, bis 8s hoch stellbar (Denkpausen). In den Settings
|
||||
// unter "Stille-Toleranz" konfigurierbar.
|
||||
export const STT_ENDPOINT_DEFAULT_MS = 2400;
|
||||
export const STT_ENDPOINT_MIN_MS = 1000;
|
||||
export const STT_ENDPOINT_MAX_MS = 4000;
|
||||
export const STT_ENDPOINT_MAX_MS = 8000; // bis 8s: genug Zeit zum Ueberlegen
|
||||
export const STT_ENDPOINT_STORAGE_KEY = 'aria_stt_endpoint_ms';
|
||||
|
||||
export async function loadSttEndpointMs(): Promise<number> {
|
||||
|
||||
+12
-30
@@ -121,7 +121,9 @@ class VoxtralRunner:
|
||||
)
|
||||
inputs = inputs.to(VOXTRAL_DEVICE, dtype=torch.bfloat16)
|
||||
with torch.no_grad():
|
||||
outputs = model.generate(**inputs, max_new_tokens=512)
|
||||
# hoch genug fuer lange Diktate (stoppt eh am EOS); 512 hat
|
||||
# mehrminutige Aufnahmen abgeschnitten.
|
||||
outputs = model.generate(**inputs, max_new_tokens=4096)
|
||||
trimmed = outputs[:, inputs.input_ids.shape[1]:]
|
||||
text = proc.batch_decode(trimmed, skip_special_tokens=True)
|
||||
return (text[0] if text else "").strip()
|
||||
@@ -284,40 +286,20 @@ class SessionManager:
|
||||
return
|
||||
if self._buffer_ms(sess) < STREAM_MIN_AUDIO_MS:
|
||||
return
|
||||
# adaptive akustische Sprach-Aktivitaet
|
||||
# Adaptive akustische Sprach-Aktivitaet (M0.1). KEINE Live-Partials mehr:
|
||||
# Voxtral-3B transkribiert den ganzen WACHSENDEN Buffer und braucht dafuer
|
||||
# bei langen Aufnahmen 5-6 s — zu langsam fuer Live-Text, UND diese Latenz
|
||||
# hat den semantischen Endpoint faelschlich ausgeloest (Partial-Latenz >
|
||||
# Timeout → willkuerliche Abbrueche nach 20-40 s). Deshalb: Turn-Ende rein
|
||||
# AKUSTISCH, transkribiert wird nur EINMAL im _finalize.
|
||||
rms = self._tail_rms(sess)
|
||||
if rms >= self._voice_threshold(sess):
|
||||
sess.last_voice_at = now
|
||||
else:
|
||||
self._update_noise_floor(sess, rms)
|
||||
# Endpoint-Entscheidung, sobald Text erkannt wurde
|
||||
if sess.last_growth_at > 0.0:
|
||||
ac_sil = (now - sess.last_voice_at) * 1000.0 if sess.last_voice_at > 0 else 0.0
|
||||
se_sil = (now - sess.last_growth_at) * 1000.0
|
||||
ac_done = sess.last_voice_at > 0 and ac_sil >= sess.endpoint_ms
|
||||
se_done = se_sil >= sess.endpoint_ms * STREAM_SEMANTIC_BACKUP_FACTOR
|
||||
if ac_done or se_done:
|
||||
await self._finalize(sess, "endpoint" if ac_done else "endpoint_semantic")
|
||||
return
|
||||
# Partial-Transkription (throttled)
|
||||
if (now - sess.last_transcribe_at) * 1000.0 < STREAM_TRANSCRIBE_INTERVAL_MS:
|
||||
return
|
||||
sess.last_transcribe_at = now
|
||||
audio = pcm_s16le_to_float32(bytes(sess.pcm_buffer))
|
||||
try:
|
||||
text = (await self.runner.transcribe(audio, sess.language)).strip()
|
||||
except Exception:
|
||||
logger.exception("Stream %s: Partial-Transcribe crashed", sess.request_id[:8])
|
||||
return
|
||||
if text and text != sess.last_partial:
|
||||
sess.last_partial = text
|
||||
sess.last_growth_at = now
|
||||
if self._ws is not None:
|
||||
await _send(self._ws, "stt_partial", {
|
||||
"requestId": sess.request_id,
|
||||
"audioRequestId": sess.audio_request_id,
|
||||
"text": text,
|
||||
})
|
||||
# Endpoint: hat der User schon gesprochen UND ist es seit endpoint_ms still?
|
||||
if sess.last_voice_at > 0 and (now - sess.last_voice_at) * 1000.0 >= sess.endpoint_ms:
|
||||
await self._finalize(sess, "endpoint")
|
||||
|
||||
async def _finalize(self, sess: StreamSession, reason: str) -> None:
|
||||
if sess.endpoint_sent:
|
||||
|
||||
Reference in New Issue
Block a user