A local, fully offline sound-awareness assistant for people with hearing impairments. Sentilo listens through the microphone, detects sound events (door knocks, alarms, speech, etc.), estimates their direction, and surfaces clear alerts in a compact UI — all on-device with no cloud dependency.
cd frontend
npm run tauri dev
This repository combines:
backend/: Python pipeline for microphone capture, SED, DOA, grouping, and alert generation.backend/modules/: local implementations for SED, DOA, and LLM reasoning.backend/contracts/: shared dataclass contracts and pipeline configuration.backend/pipeline/: async audio routing, raw event emission, and per-window grouping.frontend/: Tauri + React + TypeScript UI that consumes alerts from the backend.third_party/PretrainedSED/: upstream PretrainedSED framework for the SED model.resources/: model checkpoint assets used by the pipeline.
The backend is a local Python process that runs entirely on-device.
backend/main.pyis the CLI entrypoint.backend/pipeline/audio_io.pyopens the system microphone usingsounddevice, buffers audio in a stereo ring buffer, and emits overlapping sliding windows asRawChunkobjects.backend/pipeline/orchestrator.pyconsumes raw windows with an async pipeline:- SED gate: skip quiet windows using RMS and run SED only on candidate windows.
- DOA stage: estimate direction and distance for detected events.
- Event grouping: merge consecutive same-class windows into a single alert.
- LLM reasoning: add a human-facing alert message and priority.
backend/pipeline/event_bus.pywrites machine-readable JSON lines to stdout. The Tauri sidecar reads this stdout stream and bridges it into the frontend.
backend/modules/sed/: wraps the PretrainedSED framework and exposesSEDModel.detect().- Uses
M2Dencoder by default. - Loads the downloaded
M2D_strong_1.ptcheckpoint fromresources/. - Collapses frame-level multi-label probabilities into one top
SoundClassand confidence per window.
- Uses
backend/modules/doa/: real GCC-PHAT direction-of-arrival engine.- Auto-calibrates microphone spacing during startup.
- Returns a direction in degrees and class-agnostic distance-related measurements.
backend/modules/llm/: local Ollama-backed alert text generator.- Maps sound class to deterministic priority.
- Uses a cached, low-latency prompt to generate short user-facing messages.
- Falls back safely if Ollama is unavailable.
The frontend is a Tauri + React app in frontend/.
frontend/src/hooks/useAlertStream.ts: listens foralert,raw_event, andsystem_infoevents from the Tauri runtime.frontend/src/App.tsx: displays an alert feed, radar visualization, and message UI.- The app supports a mock feed when running in the browser instead of inside Tauri.
Key directories and files:
backend/pipeline/: audio capture, orchestrator, event grouping, and offline file runner.backend/contracts/: typed dataclasses for SED, DOA, LLM, and final alerts.backend/modules/sed/: SED detector wrapper, ontology mapping, and model loader.backend/modules/doa/: DOA engine wrapper and distance estimation.backend/modules/llm/: local alert reasoning, priority mapping, and caching.frontend/package.json: app scripts, dependencies, and Tauri integration.frontend/src/: React UI components, hooks, and types.
From the repository root:
python -m venv .venv
.venv\Scripts\activate # Windows
# or: source .venv/bin/activate # macOS/Linux
pip install -e .[dev]Install the PretrainedSED framework and ensure the checkpoint is available:
cd backend
bash scripts/setup_pretrainedsed.shIf you cannot run the install script, place M2D_strong_1.pt manually into:
backend/resources/M2D_strong_1.ptresources/M2D_strong_1.ptfrontend/resources/M2D_strong_1.pt
Install frontend dependencies:
cd frontend
npm installThe local LLM alert generator expects a running Ollama server and the gemma3:1b model.
If Ollama is not installed, the backend will still run and emit fallback alert text.
If you have the Sentilo.app bundle (from a release or built yourself):
- Double-click
Sentilo.appin Finder, or run from the terminal:open "/path/to/Sentilo.app" - On first launch macOS may show a security prompt. If the app is unsigned, right-click → Open → Open to bypass Gatekeeper, or run:
xattr -cr "/path/to/Sentilo.app" - Grant microphone access when prompted — Sentilo needs it to detect sounds.
The app starts immediately in live microphone mode. No Python, Node, or Rust installation required.
From the repo root, after completing the Setup steps:
cd frontend
npm run tauri devThis starts the React dev server and launches Tauri with hot-reload.
Run backend tests from the repository root:
pytestFast tests only:
pytest -v -k 'not real'- The system is designed to stay fully local. No external network requests are made by the audio pipeline itself.
- The frontend reads backend events through Tauri and does not talk directly to the Python process.
- The backend emits structured JSON lines on stdout so the Tauri sidecar can forward them reliably.
backend/pipeline/orchestrator.pygates DOA and LLM work behind detected SED windows to save compute.
docs/infernceclass.md: SED class ontology and macro mapping.backend/scripts/benchmark_latency.py: pipeline latency benchmarking.backend/scripts/test_doa.py: DOA debugging and unit tests.frontend/src/: UI implementation and event handling.