Commit Graph
618 Commits
Author SHA1 Message Date
iamdoubz 0b5a85f461 feat(diarization): persist mic_activity.json; reprocess uses the Phase 3 timeline (FR-SPK)
Factor the Phase 3 attribution (you_spans -> mask -> diarize far side -> merge +
name) into a shared phase3_attribute() used by both stop and reprocess. stop now
writes mic_activity.json (the 'You' spans) next to a retained audio.wav
(plaintext timing metadata, local-only, lives/dies with audio.wav); reprocess
prefers that timeline over the voiceprint fallback so re-transcription keeps
correct per-stream 'You'/'Speaker' attribution.
2026-07-14 00:51:41 -05:00
iamdoubz fd9311c482 feat(diarization): Phase 3 stop attribution — mic timeline is 'You', diarize far side masked (FR-SPK)
stop_recording now, when the mic is on, takes 'You' spans straight from the
MicActivity timeline and diarizes the recording with those ranges zeroed, so
sherpa only ever clusters the far side into Speaker N. Merges the span lists and
names them via the existing voiceprint map (You + Speaker 2..). Falls back to
the whole-signal pass + voiceprint match when the mic is off. Adds mask_ranges
helper + tests.
2026-07-14 00:04:58 -05:00
iamdoubz 39294adcbc feat(audio): populate MicActivity timeline from the loopback writer (FR-SPK) 2026-07-14 00:04:57 -05:00
iamdoubz fee18ebc59 refactor(diarization): expose first_appearance_order + build_name_map to crate (FR-SPK) 2026-07-14 00:04:56 -05:00
iamdoubz 51f5ff085c feat(diarization): Diarizer::diarize_samples + short-input guard for masked far-side pass (FR-SPK) 2026-07-14 00:04:55 -05:00
iamdoubz 6d4204fb22 feat(recording): RecordingSession.mic_activity for Phase 3 attribution (FR-SPK) 2026-07-14 00:04:54 -05:00
iamdoubz 185489fa18 feat(audio): MicActivity timeline for Phase 3 per-stream 'You' attribution (FR-SPK)
Records, per 100ms of audio.wav frame time, when the mic (the user) was
speech-level — captured in the loopback writer where mic and loopback exist
separately in the recording's own timebase. you_spans() collapses active
windows into merged 'You' ranges. The far side will be diarized with these
ranges masked out, so clustering never sees the mic. Struct + span logic land
first (tested); capture wiring + stop attribution follow.
2026-07-13 21:15:49 -05:00
iamdoubz 41c2c79797 docs(plan): finalize Phase 3 design — mic=You, diarize loopback-masked (FR-SPK) 2026-07-13 21:15:48 -05:00
iamdoubz 6dd6c3c69f fix(audio): capture mic during system-audio silence (FR-CAP-7)
WASAPI loopback delivers no packets when the render endpoint is idle, so the
recording only advanced while system audio played. The bridged mic (the user
talking over silence) was lost to MicBridge overflow, and audio.wav lost those
stretches entirely — corrupting diarization and dropping the user's solo
remarks in real meetings. When loopback is idle, synthesize silence for the
elapsed gap and fold the mic in, keeping audio.wav continuous. Loopback +
mic-enabled only.
2026-07-13 20:58:23 -05:00
iamdoubz 9468781218 fix(audio): gate voiceprint capture on mic energy so it's real speech (FR-SPK)
VoiceSample kept the first N samples unconditionally, so a user silent for the
first 30s got a voiceprint of room noise/a cough. That noise embedding
spuriously matched a cluster and mislabeled every speaker 'You', even during
silence. Skip sub-threshold (VOICE_ENERGY_FLOOR) chunks so the window tracks
actual speech; until ~1s of real voice accumulates, the match returns empty
(no premature 'You').
2026-07-13 20:35:25 -05:00
iamdoubz b39352dbff fix(diarization): clear stale speaker rows on reprocess so Participants pane matches (FR-SPK)
Reprocess re-diarizes and upserts the new labels but never deleted the old
ones, so get_meeting (Participants pane) kept returning the discarded run's
labels (e.g. 83) while the transcript showed the new 5. Clear the meeting's
speaker rows before finalize re-inserts the fresh set.
2026-07-13 20:09:03 -05:00
iamdoubz 0d263637df feat(storage): Store::clear_speakers to drop a meeting's speaker rows (FR-SPK) 2026-07-13 20:09:01 -05:00
iamdoubz bb6e222101 docs(plan): Phase 3 per-stream attribution design sketch + ADR-0005 review (FR-SPK) 2026-07-13 19:32:15 -05:00
iamdoubz 85ed3b5587 docs(api-contracts): note transcript://segment re-emit + live diarization://updated (FR-SPK) 2026-07-13 19:25:31 -05:00
iamdoubz 68d692fbe8 fix(transcript): resolve live speaker names incl 'You' in the recording view (FR-SPK) 2026-07-13 19:25:30 -05:00
iamdoubz fa664e5147 feat(recording): live speakers state from diarization://updated (FR-SPK) 2026-07-13 19:25:29 -05:00
iamdoubz b5c99621b5 feat(api): onDiarizationUpdated event listener for live speaker updates (FR-SPK) 2026-07-13 19:25:28 -05:00
iamdoubz db52b9e812 feat(diarization): live tick re-emits relabeled segments + live 'You' (FR-SPK)
Phase 2 backend. The 15s provisional pass now (1) runs the mic voiceprint
match every tick and merges 'You'/'Speaker N' into the session name map without
overwriting user-set names, and (2) re-emits every committed segment whose
speaker changed via transcript://segment (replace-by-id) so the live transcript
reflects the refined labels instead of a frozen 'S1'.
2026-07-13 19:25:27 -05:00
iamdoubz 319e7a31cc docs(data-model): add voiceprint.wav to the meeting dir file list (FR-SPK) 2026-07-13 19:19:06 -05:00
iamdoubz 25011d0f27 fix(diarization): reprocess re-diarizes + persist mic voiceprint.wav (FR-SPK)
Phase 1. stop_recording writes voiceprint.wav next to a retained audio.wav
(ADR-0009 gated, sealed at rest with the vault); reprocess_transcript now
re-diarizes the fresh transcript and rebuilds the speaker name map from the
voiceprint instead of reusing the stale original-run names, fixing the
collapse to a single 'You' speaker on re-transcription.
2026-07-13 19:19:06 -05:00
iamdoubz 7733e86cfd feat(audio): write_wav_mono_16k helper for persisting the mic voiceprint (FR-SPK) 2026-07-13 19:19:05 -05:00
iamdoubz a481f5dcbf fix(diarization): tame cluster explosion with threshold 0.7 + 700ms min span (FR-SPK)
Phase 0 of the speaker-accuracy plan. sherpa fast-clustering threshold 0.5
over summed mic+loopback mono exploded a 2-speaker call into 83 clusters;
raise to 0.7 (larger threshold -> fewer clusters) and drop sub-700ms spans
whose embeddings are unstable and only churn labels in assign_by_overlap.
2026-07-13 19:12:04 -05:00
iamdoubz bd6519b65e docs(plan): phased fix plan for diarization speaker accuracy (FR-SPK) 2026-07-13 18:40:44 -05:00
iamdoubz 4f3af98bfa Add Clippy marketing image v0.5.2 2026-07-13 16:15:18 -05:00
iamdoubz 77f9a8b518 docs(readme): bump status to v0.5.2 and add UI-localization comparison row 2026-07-13 16:07:12 -05:00
iamdoubz 2a7e6229f4 docs(readme): list the 20 available interface languages and RTL support 2026-07-13 16:05:12 -05:00
iamdoubz 64e7baad66 docs(release): v0.5.2 release notes with SHA-256 checksums 2026-07-13 16:00:00 -05:00
iamdoubz 804d451bfa chore(release): bump version to 0.5.2 2026-07-13 15:59:58 -05:00
iamdoubz a29e60b47d fix(storage): show native error dialog on startup DB failure instead of panic
A migration-checksum mismatch (an edited-after-shipping migration) made
SqliteStore::connect() return Err, which .expect() turned into a panic=abort
fast-fail: the window never opened and the OS reported only a 0xc0000409 crash.
Replace the expect with a blocking MessageBoxW that names the failure and points
at wa.db, then exit(1) cleanly.
2026-07-13 15:52:55 -05:00
iamdoubz 969ed6022e build(deps): enable Win32_UI_WindowsAndMessaging for startup error dialog 2026-07-13 15:52:54 -05:00
iamdoubz 226593b49d Merge pull request 'Bump version 0.5.0' (#22) from bump_version_0.5.0 into main
Reviewed-on: #22
v0.5.1
2026-07-13 08:46:24 -05:00
iamdoubz dc1d352e09 docs(release): v0.5.1 release notes with SHA-256 checksums 2026-07-12 22:47:48 -05:00
iamdoubz 05e003ab19 chore(release): bump version to 0.5.1 2026-07-12 22:41:45 -05:00
iamdoubz d636eec848 feat(i18n): register 19 locales and flip document dir for RTL (ar, ur) 2026-07-12 20:12:45 -05:00
iamdoubz 1aeaae3550 feat(i18n): add Urdu (ur) translation 2026-07-12 20:12:44 -05:00
iamdoubz 84774c75cb feat(i18n): add Arabic (ar) translation 2026-07-12 20:07:27 -05:00
iamdoubz bca790571c feat(i18n): add Sinhala (si) translation 2026-07-12 20:04:27 -05:00
iamdoubz bfe7005368 feat(i18n): add Tamil (ta) translation 2026-07-12 16:27:57 -05:00
iamdoubz e01d61ae0c feat(i18n): add Bengali (bn) translation 2026-07-12 16:21:00 -05:00
iamdoubz 8947eb2f39 feat(i18n): add Hindi (hi) translation 2026-07-12 16:17:15 -05:00
iamdoubz d2ef12269b feat(i18n): add Korean (ko) translation 2026-07-12 16:13:53 -05:00
iamdoubz bab1eb57b1 feat(i18n): add Mandarin Chinese Simplified (zh-CN) translation 2026-07-12 16:11:17 -05:00
iamdoubz 76bb38cbe6 feat(i18n): add Finnish (fi) translation 2026-07-12 16:09:01 -05:00
iamdoubz 7570d810e4 feat(i18n): add Norwegian Bokmal (nb) translation 2026-07-12 16:05:22 -05:00
iamdoubz a090cc4acd feat(i18n): add Swedish (sv) translation 2026-07-12 16:02:27 -05:00
iamdoubz 7f0a718210 feat(i18n): add Russian (ru) translation 2026-07-12 15:59:42 -05:00
iamdoubz 96e8723cb9 feat(i18n): add Portuguese (Brazil, pt-BR) translation 2026-07-12 15:57:11 -05:00
iamdoubz fce3a6b96c feat(i18n): add Portuguese (Portugal, pt-PT) translation 2026-07-12 15:54:48 -05:00
iamdoubz 0f8288f90f feat(i18n): add French (Canada, fr-CA) translation 2026-07-12 15:52:25 -05:00
iamdoubz 8ffc015e29 feat(i18n): add French (France, fr-FR) translation 2026-07-12 15:49:42 -05:00