Initial commit: audio-chat with fixes
- Created AGENTS.md with architecture documentation - Fixed race conditions and async patterns - Added conversation history to LLM prompts - Fixed TTS audio shape handling - Added buffer limits and graceful shutdown - Fixed client.py with file sending support - Removed duplicate requirements - Added .gitignore
This commit is contained in:
50
audio/stream.py
Normal file
50
audio/stream.py
Normal file
@@ -0,0 +1,50 @@
|
||||
import threading
|
||||
import time
|
||||
from config import Config
|
||||
|
||||
|
||||
class AudioStreamBuffer:
|
||||
def __init__(self):
|
||||
self.config = Config()
|
||||
self.buffer = b""
|
||||
self.lock = threading.Lock()
|
||||
self.event = threading.Event()
|
||||
self.running = False
|
||||
# Limit buffer to 10 seconds of audio to prevent OOM
|
||||
self.max_buffer_bytes = int(self.config.SAMPLE_RATE * 10 * 2)
|
||||
|
||||
def start(self):
|
||||
self.running = True
|
||||
self.buffer = b""
|
||||
self.event.clear()
|
||||
|
||||
def add_chunk(self, chunk: bytes):
|
||||
with self.lock:
|
||||
self.buffer += chunk
|
||||
# Evict oldest data if buffer exceeds limit
|
||||
if len(self.buffer) > self.max_buffer_bytes:
|
||||
self.buffer = self.buffer[-self.max_buffer_bytes // 2:]
|
||||
if len(self.buffer) >= self.config.CHUNK_SIZE:
|
||||
self.event.set()
|
||||
|
||||
def get_ready_chunk(self, timeout: float = 1.0) -> bytes:
|
||||
if self.event.wait(timeout=timeout):
|
||||
with self.lock:
|
||||
chunk = self.buffer
|
||||
self.buffer = b""
|
||||
self.event.clear()
|
||||
return chunk
|
||||
return b""
|
||||
|
||||
def get_full_buffer(self) -> bytes:
|
||||
with self.lock:
|
||||
chunk = self.buffer
|
||||
self.buffer = b""
|
||||
return chunk
|
||||
|
||||
def stop(self):
|
||||
self.running = False
|
||||
self.event.set()
|
||||
|
||||
def is_running(self):
|
||||
return self.running
|
||||
Reference in New Issue
Block a user