Commit Graph
31 Commits
Author SHA1 Message Date
thomas.kopp 52e55e112f fix: build PipeWire capture chain on demand instead of permanently
The null sink and its two loopbacks were loaded at startup and stayed
loaded forever. While loaded they link the microphone and the speaker
device into a single PipeWire driver group: the microphone drives the
graph and the speaker device runs as a clock follower, so every playback
stream pays for continuous cross-device resampling.

Nothing needs the chain while idle — recording is triggered manually.
Build it in toggle_recording() and drop it as soon as the audio is
captured, before transcription runs for minutes.

Module ids are now derived from pactl instead of tracked in a state file,
so a crashed process cannot leave stale ids behind. The state file only
holds the device selection. Startup tears down any leftover chain.

Loopbacks get latency_msec=200; transcription is offline, and a small
buffer would put these nodes on the graph's realtime deadline.
2026-08-02 01:25:15 +02:00
thomas.kopp 6b0ee60d94 fix: cache pyannote diarization pipeline to stop memory leak / OOM
The meeting pipeline created a fresh Diarizer per recording, each loading
the multi-GB pyannote speaker-diarization model anew (api/pipeline.py).
Whisper and Ollama run remotely in this deployment, so pyannote was the
only heavy in-process consumer. Reloading it per recording leaked CPU
memory (torch reference cycles + glibc arena fragmentation) that was
never returned to the OS, climbing to a 37 GB peak over a multi-day run
until the kernel OOM-killed the service.

Cache the loaded pipeline on the class and reuse it across Diarizer
instances, mirroring TranscriptionEngine._model. RSS now stays flat.
2026-07-22 09:03:42 +02:00
thomas.koppandClaude Sonnet 4.6 336628341b feat: AI-generated title+tldr, subfolder structure, backlinks in transkript/zusammenfassung
- llm: generate_title_and_tldr() returns concise title and 2-3 sentence summary
- output: index in root, transkript+zusammenfassung in {base}/ subdir with backlinks
- pipeline: call generate_title_and_tldr for both solo and meeting recordings
- router: mirror subdir structure when copying to Obsidian vault

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 12:07:54 +02:00
thomas.koppandClaude Sonnet 4.6 180fe43df7 fix: handle pyannote 4.x DiarizeOutput wrapper in diarize()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 11:34:02 +02:00
thomas.koppandClaude Sonnet 4.6 06f7361004 feat: write 3 files per solo recording (index + transkript + zusammenfassung)
- pipeline: call write_solo_docs() instead of save_transcript(); broadcast paths dict
- router: /open accepts paths list for Obsidian mode, copies all 3 files to vault
- app.js: store _modalPaths from saved event; Obsidian button sends all paths
- tests: test_write_solo_docs_creates_three_files added

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 11:10:28 +02:00
thomas.kopp b4e7e08918 fix: update audio devices test to mock sounddevice instead of pactl 2026-04-02 07:52:34 +02:00
thomas.kopp 37e432f7fa feat: POST /speakers — resolves pipeline pause with speaker name mapping 2026-04-02 01:07:41 +02:00
thomas.kopp dbb35ce71d feat: AppState gains speaker pause fields and AWAITING_SPEAKERS status 2026-04-02 01:06:30 +02:00
thomas.kopp 033c1fc486 feat: write_meeting_docs() — creates index, transkript, zusammenfassung 2026-04-02 01:05:07 +02:00
thomas.kopp 9b5b89e159 feat: OllamaClient.identify_speakers() and summarize() for diarization pipeline 2026-04-02 01:03:40 +02:00
thomas.kopp b8cc8a3b33 feat: align_segments() — map Whisper timestamps to pyannote speakers 2026-04-02 01:00:58 +02:00
thomas.kopp 1a9d0eacc2 feat: Diarizer class wrapping pyannote/speaker-diarization-3.1 2026-04-02 00:59:50 +02:00
thomas.kopp 47909637a8 feat: transcribe_file returns timestamped segments when with_segments=True 2026-04-02 00:55:53 +02:00
thomas.kopp 7dfc0e0c5f feat: add diarization config defaults (enabled=false, hf_token) 2026-04-02 00:53:53 +02:00
thomas.koppandClaude Sonnet 4.6 81fbbfb56e feat: status includes is_admin, gear icon in header for admins
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 20:45:33 +02:00
thomas.kopp 2376bf5d71 fix: PUT /config deep-merges nested config instead of shallow update
Replaces cfg.update(body) with _deep_merge so partial updates (e.g.
setting whisper.base_url) no longer wipe sibling keys. Also persists
the merged config back to disk via tomli_w. Adds test_put_config_deep_merges.
2026-04-01 20:40:40 +02:00
thomas.kopp ff68827280 fix: module_ids as integers in response, add 403 test for POST /audio/combined 2026-04-01 20:38:43 +02:00
thomas.kopp 478a1ac9d0 feat: GET /audio/devices, POST /audio/combined — PipeWire source management 2026-04-01 20:36:27 +02:00
thomas.koppandClaude Sonnet 4.6 ef4aa2a840 feat: AudioRecorder accepts device param — reads audio.device from config
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 20:32:44 +02:00
thomas.kopp 8300851e77 feat: remote Whisper via whisper.base_url — OpenAI-compatible upload 2026-04-01 20:28:31 +02:00
thomas.kopp 912b333124 feat: add audio.device and whisper.base_url to config defaults 2026-04-01 20:25:48 +02:00
thomas.kopp ae3ae61593 feat: DELETE /transcripts/{filename} — delete transcript with path-confinement check 2026-04-01 14:13:02 +02:00
thomas.kopp aa3eef8fb1 feat: GET /transcripts/{filename} — serve transcript content 2026-04-01 14:12:30 +02:00
thomas.kopp d60d6bb1be fix: test_config_loads_defaults — remove reload() that undid CONFIG_PATH patch 2026-04-01 13:49:21 +02:00
thomas.kopp 1466a1529f feat: multi-user auth — per-user spaces, pbkdf2 passwords, session tokens, login page 2026-04-01 08:39:16 +02:00
thomas.kopp 319db8c788 feat: API router + pipeline — toggle, status, transcripts, WebSocket, auth stub 2026-04-01 02:26:47 +02:00
thomas.kopp 927e75aa5e feat: audio module — sounddevice recorder with WAV export 2026-04-01 02:22:53 +02:00
thomas.kopp 3976ecb52e feat: transcription module — faster-whisper with ROCm auto-detect 2026-04-01 02:22:03 +02:00
thomas.kopp 333898c5ab feat: LLM module — Ollama client with transcript refinement 2026-04-01 02:20:56 +02:00
thomas.kopp 6775f98259 feat: output module — Markdown file writer with slugified filenames 2026-04-01 02:14:57 +02:00
thomas.kopp 8a39d8b97e feat: config module with TOML defaults 2026-04-01 02:14:14 +02:00