Files
Owner/src/owner_voice_pet/protocols.py
T

119 lines
2.3 KiB
Python

from __future__ import annotations
from collections.abc import Callable, Iterable, Sequence
from typing import Protocol
from .models import (
AudioFrame,
AudioSegment,
Message,
PlaybackResult,
ReplyDelta,
Transcript,
TransportHealth,
VadResult,
WakeEvent,
)
class AudioTransport(Protocol):
def start_input(
self, device_id: str | None = None, sample_rate: int = 16000, channels: int = 1
) -> None:
...
def read_frames(self, timeout_ms: int) -> list[AudioFrame]:
...
def play_pcm(self, segment: AudioSegment, interrupt: bool = False) -> PlaybackResult:
...
def play_pcm_chunks(
self,
segment: AudioSegment,
*,
chunk_ms: int,
after_chunk: Callable[[AudioSegment, int], bool] | None = None,
should_stop: Callable[[], bool] | None = None,
) -> PlaybackResult:
...
def flush_input(self) -> int:
...
def stop(self) -> None:
...
def health(self) -> TransportHealth:
...
class WakeWordProvider(Protocol):
def load(self) -> None:
...
def detect(self, frame: AudioFrame) -> WakeEvent | None:
...
def reset(self) -> None:
...
class AudioPreprocessor(Protocol):
def load(self) -> None:
...
def reset(self) -> None:
...
def process_frame(self, frame: AudioFrame) -> AudioFrame:
...
def flush(self) -> list[AudioFrame]:
...
class VadProvider(Protocol):
def load(self) -> None:
...
def analyze(self, frame: AudioFrame) -> VadResult:
...
def reset(self) -> None:
...
class SttProvider(Protocol):
def load(self) -> None:
...
def transcribe(self, segment: AudioSegment) -> Transcript:
...
class RealtimeTranscriptSession(Protocol):
def accept_frame(self, frame: AudioFrame) -> Transcript | None:
...
def finish(self) -> Transcript | None:
...
class RealtimeSttProvider(SttProvider, Protocol):
def start_stream(self) -> RealtimeTranscriptSession:
...
class LlmProvider(Protocol):
def stream_reply(self, messages: Sequence[Message]) -> Iterable[ReplyDelta]:
...
class TtsProvider(Protocol):
def load(self) -> None:
...
def synthesize(self, text: str) -> AudioSegment:
...