Spaces:
Paused
Paused
File size: 2,098 Bytes
68b18cf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | """
ASR + Audio Diarizer — speaker-separated evidence ledger
A_t = {S_0(t), S_1(t), S_2(t), N(t), E(t)}
S_0 = user, S_1 = TV/background, S_2 = other speaker, N = noise, E = events
Browser-side speech recognition provides the transcript.
This module assigns speaker labels and confidence.
"""
import hashlib
import time
from .stream_state import AudioChunk, sha256_text
def process_transcript(text: str, state) -> AudioChunk:
"""Process a transcript chunk from the browser.
The browser sends transcript text (from SpeechRecognition API).
We assign speaker label "user" by default since it's the primary mic.
"""
chunk = AudioChunk(
ts=time.time(),
chunk_id=f"chunk_{int(time.time() * 1000)}",
duration_ms=len(text) * 50, # rough estimate
speaker="user",
transcript=text.strip(),
confidence=0.85, # browser ASR confidence placeholder
sha256=sha256_text(text),
is_speech=bool(text.strip()),
)
return chunk
def assign_speaker(text: str, existing_speakers: dict) -> str:
"""Heuristic speaker assignment.
In a full system, this would use pyannote/WhisperX diarization.
For now, we use simple heuristics:
- If text matches known user patterns → "user"
- If text seems like TV/background → "background"
- Otherwise → "unknown"
"""
text_lower = text.lower()
# Check if this looks like user instruction
instruction_words = ["build", "make", "generate", "create", "show", "run", "fix", "code"]
if any(w in text_lower for w in instruction_words):
return "user"
# Check if it matches existing user transcript patterns
if "user" in existing_speakers:
user_text = existing_speakers["user"].get("transcript", "").lower()
# Simple word overlap check
user_words = set(user_text.split())
text_words = set(text_lower.split())
overlap = len(user_words & text_words)
if overlap > 2:
return "user"
# Default to unknown (could be TV, background, another person)
return "unknown"
|