Repository navigation
Releases: baakhoff/bmeet
Release list
BMeet 0.8.1: meetings started in the same minute stay apart
Fixed
- A meeting started in the same minute as the one before lost its speaker pass and its live transcript: each meeting's recording was named after its start minute. Stopping a meeting and starting the next at once (on 2026-10-15, a meeting and then an in-person one, both at 11:35) put the second recording into the first one's folder; when the first one's speaker pass ended, it deleted that folder, the second recording with it. The second meeting kept only voxtype's own transcript (everyone under You in person), and its audio was lost. Now a minute whose recording is still there gives the next one
-2,-3, … (voxtype-meeting-toggle), and the first pass also no longer reads the second meeting's settings. - Two meetings of one minute could swap transcripts in the app: the app paired them with their Markdown copies by modification time, which the speaker pass changes. Now a copy goes to the meeting with its title when no other copy of that minute has that title, and otherwise in the order the copies were written (a later one is named
-meeting-EPOCH.md); a meeting never gets a copy another meeting can claim by its title, nor a-meeting-EPOCH.mdcopy written long after it ended. On 2026-10-15 both copies got the second meeting's title (the first pass read the second meeting's settings), and they still pair right. The widget's recent list uses the same rule. - Two normal meetings started in one minute shared voxtype's own copy: voxtype keeps a meeting's files in a folder named after its date and title, and the titles only go down to the minute ("Meeting 2026-10-15 11:35"). The second meeting overwrote the first one's transcript there, and deleting one in the app deleted the other's. A title voxtype already has now gets " (2)", " (3)", …
- "Telling the speakers apart…" on the wrong meeting: the speaker pass's marker now names the transcript it replaces, so only that meeting shows as busy, not every meeting of its start minute (a meeting without a copy yet: by its start minute, as before).
Tests
voxtype/tests/test_meeting_toggle.py(in CI): the meeting toggle itself, with stand-ins for voxtype, systemd and the clock: one meeting, two in one minute with the first speaker pass ending while the second records, three in one minute (titles), and a minute whose pass is still stopping. The app's tests pair same-minute copies in both the app and bmeet-ctl, including the 2026-10-15 shape.
BMeet 0.8.0: the dictation text while you speak (prototype)
See the text while you dictate: a prototype, off by default.
Added
- Text while you speak (
echo on > ~/.config/bmeet/live-dictation): Meta+H uses BMeet's own dictation instead of voxtype's, and the words appear in the text field you are in as you speak. They are underlined until they are final, and each sentence goes in for good when you pause after it. Details and measurements indocs/live-dictation.md.- Into the field without the clipboard: for the length of each dictation BMeet becomes KWin's input method (the slot of System Settings → Virtual Keyboard), and afterwards puts back what was there, switched on or off as it was. What was there is noted in
~/.local/state/bmeet/input-method.jsonfirst, so a crash can't lose it. Tested with Qt, GTK 3, Chrome 155 and Konsole; X11 programs get a panel at the bottom and a paste at the end.panelinstead ofonalways does that and leaves KWin alone. - Russian (GigaAM v3): half the word errors of today's dictation on Podlodka clips (7.3 % against 16.2 %), as good as GigaAM on the whole recording, also past 30 s. The text is ~0.5 s behind your words, and ~0.2 s after the stop it is complete. CPU about as today's: ~0.4 s per minute of speech.
- English (Whisper turbo): 1.1 % word errors on LibriSpeech (today 2.7 %), ~1.2 s behind your words. It costs more CPU than Russian: ~2.3 s per minute of speech, against ~0.4 s for today's dictation. Whisper computes its audio features on the CPU for every pass.
npu-transcribe --dictateis the engine (commands on stdin, the text as it changes on stdout),bmeet-dictatethe service thatbmeet-ctl dictatestarts, andbmeet-imthe input method.npu-transcribe --dictate-file FILEdictates a file, for tests.
- Into the field without the clipboard: for the length of each dictation BMeet becomes KWin's input method (the slot of System Settings → Virtual Keyboard), and afterwards puts back what was there, switched on or off as it was. What was there is noted in
Changed
- The Meta+H and Meta+Alt+H launchers run
bmeet-ctl dictate, which goes to voxtype as before unless live dictation is on.
Tests
transcribe/tests/test_dictation.py(offline) andbmeet/dictate/tests/test_dictate.py(offscreen, and in a private headless KWin with its own D-Bus and kwinrc: text into a Wayland field, X11 fallback, cancel, the slot always given back) run in CI; the KWin part skips there.transcribe/tests/dictate_test.pymeasures the engine on real Russian and English speech on the NPU.
BMeet 0.7.1: Export gives the finished transcript
Fixed
- Export gave the transcript from before the speaker pass: Export… in the app asked voxtype for its copy of the meeting, which is the one from during the meeting: You / Remote only (in person, everything under You), without the people told apart, their names, the tidying, or the echo and muted words left out. It now exports the meeting's Markdown copy, which has all of that: as it is, or as plain text or JSON in voxtype's layouts. A running meeting exports its live transcript; voxtype's copy is used only for a meeting without a Markdown copy.
BMeet 0.7.0: the meeting transcript while the meeting runs
See what has been said while the meeting is still on.
Added
- Live meeting transcript: the BMeet window shows the running meeting's transcript as people talk, You and Remote (in person: Room), and keeps scrolling with it unless you scroll up to read. A meeting that starts while the window is open is selected. Until now nothing showed before the stop: voxtype keeps its own transcript to itself until the meeting ends.
npu-transcribe --live DIRfollows BMeet's meeting recording as it grows (unitbmeet-live, started byvoxtype-meeting-togglenext to the recorder). Each track is cut into phrases where its sound stops, and a phrase is transcribed once it has ended, on the NPU.- Russian (GigaAM): the sentence still being said shows in italics, redone every 1.5 s of it. In the tests the words showed up about 2 s before the end of a line, and the line was final 2-5 s after it. That costs ~15 s of CPU per hour of meeting (plus ~2 s to load the models).
- Other languages (Whisper turbo): a phrase at a time, ~2 s after it ends. Whisper takes more CPU: ~1.3 s per minute of meeting.
- Your microphone: what you said while muted in the call is left out, and so is the other side's echo, as in the speaker pass. The echo doesn't keep your phrase open either: only what is clearly louder than it counts as you.
- When you stop: the live transcript, finished, becomes the meeting's Markdown copy instead of voxtype's (whisper-small, without the echo and muting filters), until the speaker pass replaces it with Person 1, Person 2, …
- Off with
offin~/.config/bmeet/live-transcript. It needs the meeting audio, so not with--no-speakers.
Not changed
- Dictation still types the text when you stop. voxtype's own way of typing while you speak (
[openvino] streaming) was tested on the NPU and left off. It took 5-6x the CPU of normal dictation, dropped audio past ~25 s of speech, sometimes typed text twice, and with BMeet's paste output it would fill the clipboard history with fragments and lose the last words (details indocs/voxtype.md).
Tests
transcribe/tests/meeting_test.py --live: records the made-up meeting of real voices again in real time while--livefollows it, and reports how soon each line showed up. All lines showed in Russian and English, with echo, with headphones, muted and in person; none of the other side's words were under You, and nothing said while muted.
BMeet 0.6.0: speakers told apart by Nemotron 3 Diarization
Telling the speakers apart with NVIDIA's Nemotron 3 Diarization, on the NPU: far less speech under the wrong person, in Russian first of all.
Changed
- Who speaks when: NVIDIA's Nemotron 3 Diarization (September 2026, OpenMDW-1.1) replaces pyannote segmentation + clustered TitaNet fingerprints, still on the NPU. Measured on real recordings (
transcribe/tests/speakers_test.py):- Russian podcasts (4.1 h, 2-3 people): speech under the wrong person 8.1 % → 2.1 %.
- AMI meetings recorded by one microphone in the room (9 h, 3-4 people): 22.8 % → 8.4 %; diarization error rate 42.3 % → 11.0 %; the right number of people in 15 of 16 meetings instead of 4.
- Someone who says little: a phrase of about 5 s or more usually gets a voice of its own. Before, voices with under 15 s of speech were folded into others.
- Faster: ~16 s per hour of audio on the NPU instead of ~30 s.
- Remembered voices still use TitaNet fingerprints, so the voices you named and your own voice carry over.
- Install: the installer downloads the model (~400 MB) and
transcribe/prepare-diarizationrebuilds it for the NPU without PyTorch (~20 s, once). On the NPU it agrees with NVIDIA's reference code on 99.98 % of the 10 ms frames.NPU_DIARIZATION=pyannoteuses the way of before. - Up to 8 voices per track.
- One person as two voices: over a long recording Nemotron now and then opens a second voice for someone; voices whose fingerprints are at least 0.75 alike become one. That halved the speech under the wrong person on the Russian podcasts, to 2.1 %.
Fixed
- Their last word under You: a word the other side says just as you start talking, which your microphone picks up from the speakers, was kept in your line: the echo filter compares loudness, and you are loud there already. The same word at the same moment on both tracks is now theirs.
- Learning your own voice from long lines: only the middle 4 s of each of your lines counted, so meetings where Whisper joined your sentences into a few long lines could teach nothing (15 s needed). A long line now gives several 4 s pieces.
Tests
transcribe/tests/meeting_test.pyuses real people: four speakers of Russian podcasts (transcribed by GigaAM, as in a meeting) or four LibriSpeech readers, downloaded into the work folder. Every case comes out with 100 % of the words under the right label, in both languages. Nemotron often hears espeak's synthetic voices as one person, so--espeaknow checks only your label, the echo and muting.transcribe/tests/speakers_test.py: who speaks when on the Russian podcasts and (--ami) the AMI meetings.
Install or update:
curl -fsSL https://raw.githubusercontent.com/baakhoff/bmeet/main/install.sh | bashThe update downloads Nemotron 3 Diarization (~400 MB) once and builds it for the NPU (~20 s).
BMeet 0.5.2: English terms in Russian transcripts
English terms in Russian speech come out right far more often.
Added
- English terms in Russian transcripts: GigaAM, used for Russian, garbles English words ("Data Dog", "worниiнг statemont", "Рuби, Пиtн") or writes them in Cyrillic, while Whisper hears most of them. Now the sentences in which GigaAM wrote Latin letters also go to Whisper, and each English word Whisper heard replaces the GigaAM word at the same moment that sounds like it.
- Russian endings stay ("warning-и", "GPU-шки", "Go-разработчиков"), words that don't sound alike are never touched, and words the two models agree on keep GigaAM's spelling.
- Measured on 33 min of a Russian IT podcast with 98 English terms (Podlodka): word errors went from 7.05 % to 6.52 %, and the English terms written right from 22 % to 54 %. Whisper turbo alone gets 58 % of the terms but 8.2 % word errors.
- Cost: Whisper ran on 12 % of the audio, which took 29 s on the NPU and 12 s of CPU for the 33 minutes. Expect a minute or two more per hour of a term-heavy meeting.
npu-transcribe --no-english-termsturns it off.transcribe/tests/english_terms_test.pyreruns the measurement.
Upgrade
curl -fsSL https://raw.githubusercontent.com/baakhoff/bmeet/main/install.sh | bashBMeet 0.5.1: transcripts found, tidier text, nothing on the CPU
Fixes from the first real in-person meeting, tidier text, and nothing slips onto the CPU.
Fixed
- Missing transcripts: the app and the widget showed voxtype's rough live draft ("no Markdown copy") instead of the speaker pass's transcript. That happened when voxtype's start time fell in the next minute after the file's stamp: a meeting stamped 15:32 was started at 15:33:00 by voxtype's clock. A file stamped a minute either side now counts when its title is the meeting's.
- Whisper loops ("Я в рейтинге. Я в рейтинге. …" for a minute) are said once. That covers a phrase repeated 3 or more times, a word 5 or more times, and the same line 3 or more times in a row.
- Never quietly onto the CPU:
- A Whisper block now writes at most 400 tokens. Without that cap, a loop overflowed the NPU decoder, and every later block failed on the NPU.
- A block that still fails is retried once on the NPU and then skipped.
- Before, the first failure moved the rest of the run to the CPU: 23 minutes of CPU time for 10 minutes of meeting. The CPU is now used only after 3 failed blocks in a row, which means the NPU itself is broken.
- Odd language guesses: a language that is not one of yours (
~/.config/bmeet/languages) is checked on the next 30 s. Whisper had taken synthetic Russian for Polish and Latin. - In person: a few seconds with no voice found are now You, not Person ?, and a line that was only a punctuation mark is dropped.
Added
- Tidier text: fillers (э-э, а-а, хмм, эмм, um), stutters ("функцио функционал", "мы мы", "и-и-и"), Latin/Cyrillic mix-ups inside a word ("oкей", "Viкl"), and spacing around punctuation are cleaned up by fixed rules. On a real 65-minute meeting that removed 1.1 % of the words. Words said several times on purpose ("нет, нет, нет", "да да") stay.
npu-transcribe --verbatimkeeps everything. - CPU time per stage in npu-transcribe's log (the speaker pass's journal), to find what still runs on the CPU.
Tried, not shipped
- Cleaning up the text with a language model on the NPU: Qwen3-8B and Qwen3-4B-Instruct-2507, int4 as the NPU needs them, on a real Russian meeting. Asked to rewrite paragraphs, they inserted Chinese characters, cut words and left most fillers. Asked only for misheard terms, they translated Russian words, dropped words and invented terms. That would make transcripts worse in ways that are hard to spot (docs/npu-transcribe.md).
Upgrade
curl -fsSL https://raw.githubusercontent.com/baakhoff/bmeet/main/install.sh | bashBMeet 0.5.0: muted means muted, and in-person meetings
Words you say while muted in the call are left out, and meetings in the room work too.
Added
- Muted in Meet or Slack: left out. BMeet records your microphone itself, so it heard you even when the call didn't. A small Chrome extension now watches how much of your microphone's sound a Meet or Slack tab sends into the call. It sends none while you're muted, however the app mutes. The speaker pass silences your microphone for those stretches, and the transcript says how long was left out.
- It reads sound levels only, never the audio, and only on meet.google.com and app.slack.com. Its helper writes the state into the meeting being recorded (in RAM) and nowhere else.
- Load it once: chrome://extensions → Developer mode → Load unpacked →
~/.local/share/bmeet/src/bmeet/chrome/extension. Without it, nothing changes. - Tested in headless Chrome: a disabled track, a removed track, a silent track and a paused sender were each caught within about a second.
- In-person meetings (Meta+Alt+Shift+M, the app's In person button, the widget,
bmeet-ctl meeting start --in-person). Only the microphone is recorded, and the speaker pass splits it by voice into You, Person 1, Person 2, … Remembered people get their names.- Your own voice is learned from your microphone in online meetings (with remembered voices on), so in the room the voice that sounds like you is labelled You. A single voice is labelled You too.
- If you start a normal meeting in the room by habit, nobody speaks through the speakers, and the microphone is split by voice anyway.
- In the naming dialog of an in-person meeting you can write You for yourself. Remembered voices… lists your own voice and can forget it.
Changed
bmeet-meeting-audiowrites each part's start time (part-N.start), so events can be placed in the audio, and--mic-onlyrecords the microphone alone.
Upgrade
curl -fsSL https://raw.githubusercontent.com/baakhoff/bmeet/main/install.sh | bashThen load the extension once: chrome://extensions → Developer mode → Load unpacked → ~/.local/share/bmeet/src/bmeet/chrome/extension.
BMeet 0.4.0
Russian is transcribed with GigaAM v3, and everything runs on the NPU, including telling the speakers apart.
Added
- GigaAM v3 for Russian (Sber, MIT), used automatically for Russian meetings and files (detected or
--language ru).- On Russian conversation (Podlodka podcast, 16 min) it made 6.5 % word errors against Whisper turbo's 8.2 %, at ~215x realtime instead of 14x.
- The trade-off: English terms inside Russian speech come out mangled.
npu-transcribe --engine auto|whisper|gigaam, installer--no-gigaam.
transcribe/prepare-modelsmakes sherpa-onnx's int8 GigaAM export run correctly on the NPU, once, at install time. On the NPU that export wrote garbage. The int8 weights become float again, and the rotary position step, which the NPU compiler gets wrong, is folded into the query and key projections.
Changed
- Speaker separation runs on the NPU (OpenVINO) instead of the CPU (sherpa-onnx). It's a new pipeline:
- pyannote segmentation-3.0 finds up to 3 voices per 10 s window.
- TitaNet-small fingerprints them, in batches of 16, with its statistics pooling scaled so the NPU's fp16 does not underflow.
- Average-linkage clustering, threshold 0.4, then pyannote-style turn reconstruction.
- The right number of people was found in all four test calls, at ~110x realtime.
- CPU time: numpy is kept to one thread, because its BLAS threads busy-waited. A 5-minute meeting now takes 8 s of CPU in total, down from 26 s.
- Language detection: the language is detected once per recording (for meetings, on the other side), also when Whisper is chosen.
- Requirements:
sherpa-onnxis no longer needed;onnxis (install time only).
Install or upgrade
curl -fsSL https://raw.githubusercontent.com/baakhoff/bmeet/main/install.sh | bashThe upgrade downloads GigaAM v3 (~160 MB) and prepares it for the NPU once (~1-2 min).
BMeet 0.3.1
Better Russian text and far fewer phantom speakers, tuned on a real Russian call.
Fixed
- Punctuation and accuracy: npu-transcribe gives Whisper one 30 s window at a time instead of 2-minute blocks. On a real Russian call the old blocks lost most punctuation and capitals after the first window and misheard more words. English accuracy is unchanged and files transcribe faster.
- Phantom speakers: a 1:1 call came out with 24 "people". Voices with under 15 s of speech (and under 5 % of all) now join the voice they sound most like, voices at least 0.65 similar to a bigger one are merged, and short replies with no turn of their own go to the nearest speaker instead of Remote.
- Stock phrases: Whisper's stock phrases over silence ("Продолжение следует…", "Субтитры сделал DimaTorzok", "Thanks for watching!") are dropped.
Install or upgrade
curl -fsSL https://raw.githubusercontent.com/baakhoff/bmeet/main/install.sh | bash