[{"data":1,"prerenderedAt":139},["ShallowReactive",2],{"blog-en-meetre-who-said-what":3},{"id":4,"title":5,"body":6,"cover":122,"date":123,"description":124,"draft":125,"extension":126,"locale":127,"meta":128,"navigation":129,"path":130,"seo":131,"stem":132,"tags":133,"__hash__":138},"blog\u002Fblog\u002Fen\u002Fmeetre-who-said-what.md","Who said what, and why my laptop kept getting it wrong",{"type":7,"value":8,"toc":112},"minimark",[9,13,21,26,29,32,36,39,42,45,52,56,59,62,66,69,72,78,81,85,88,91,95,101],[10,11,12],"p",{},"The bug report was me, reading my own transcript, and finding out I had apparently said my colleague's half of the conversation. Confidently. With timestamps.",[10,14,15,16,20],{},"Meetre records two things during a call: your microphone and the system audio, as separate stems. That's the whole trick behind speaker labels. If sound comes out of the mic stem, it's you. If it comes out of the system stem, it's the other side. Then ",[17,18,19],"code",{},"pyannote"," splits individual voices within each side. On paper, very tidy. In my headphones, also very tidy. The trouble started the day I took the headphones off.",[22,23,25],"h2",{"id":24},"your-speakers-are-a-second-microphone-input","Your speakers are a second microphone input",[10,27,28],{},"Without headphones, the call plays out of your laptop speakers, and your microphone hears it. A moment later, slightly quieter, a bit roomier, but clearly there. So the mic stem isn't just you anymore. It's you plus a delayed copy of everyone else.",[10,30,31],{},"The original attribution decided each whole segment at once, by comparing the raw loudness of the mic against the system stem. That fails in two ways. A sentence that starts with me and ends with the other person gets one label for both. And if the echo on the mic happens to be louder than the call on the system stem, which depends on your speaker volume and your gain settings, the labels flip. That's how I ended up saying things I never said.",[22,33,35],{"id":34},"word-by-word","Word by word",[10,37,38],{},"The first real fix was to stop deciding per segment. The new attribution looks at activity per frame, relative to each stem's own noise floor instead of raw loudness, estimates how much of the call leaks into the mic from frames where only the call is active, subtracts it, and then votes per word with some smoothing. Segments get split wherever the side changes. Parakeet hands back sub-word tokens, so those had to be merged into timed words first.",[10,40,41],{},"To test it without recruiting a friend for forty takes, I built a synthetic call: text-to-speech voices, no pauses between them, a quiet mic and loud echo. Basically the worst meeting I could describe. The old logic labelled 39 of 41 sentences correctly. The new one got 41 of 41.",[10,43,44],{},"I also fixed a quieter annoyance in the same pass. Diarization sometimes invented a Speaker 2 out of a cough and a door. Clusters that hold only a small share of a side's speech now get folded into the main voice instead of becoming a phantom participant.",[10,46,47],{},[48,49],"img",{"alt":50,"src":51},"The Meetre transcript view, turns grouped by speaker with coloured gutters","\u002Fimages\u002Fblog\u002Fmeetre\u002Flibrary-transcript.png",[22,53,55],{"id":54},"then-live-captions-made-it-worse","Then live captions made it worse",[10,57,58],{},"The final transcript had time to think. Live captions don't. They re-decode a short window of audio about every 0.6 seconds, and they were transcribing the sum of both stems. With speakers on, every remote sentence was in that mix twice, offset by a moment. Parakeet did what any listener would do with two overlapping copies of the same sentence: garbled it or dropped it.",[10,60,61],{},"My first attempt was software echo suppression. Cross-correlate the loudness envelopes of both stems to estimate the delay from speaker to mic, learn the echo level, mute mic frames that carry nothing but echo, keep my own voice even when I talk over someone. It worked on my desk. At real volume, it didn't hold up. I deleted it.",[22,63,65],{"id":64},"the-fix-that-muted-me","The fix that muted me",[10,67,68],{},"The second attempt was Apple's own echo canceller. macOS has Voice Processing built into the audio engine, the same thing that makes FaceTime work without headphones. I routed the mic through it, and the result was honestly perfect: the raw mic re-transcribed the remote sentences word for word, the processed mic left nothing of them.",[10,70,71],{},"I shipped it in the morning. By afternoon I'd measured what it did to everything else. While Meetre's Voice Processing mic is running, every other app hears your microphone about 35 dB quieter. My colleagues in Teams could barely hear me. The call audio itself got ducked by about 8 dB, even with gain control off and ducking set to minimum. None of that can be fixed from my side of the API.",[73,74,75],"blockquote",{},[10,76,77],{},"A recording tool that makes you inaudible in the meeting it's recording has, in a narrow technical sense, solved privacy.",[10,79,80],{},"So Voice Processing is opt-in now, off by default, with a note that it's unsafe during calls.",[22,82,84],{"id":83},"what-actually-works","What actually works",[10,86,87],{},"The version that stuck is less clever. Live captions transcribe the system audio and the mic as two separate streams and merge the lines by time. Every line's speaker is simply its source. People talking over each other no longer garble one mixed signal. The mic stream only gets decoded where a voice activity detector (Silero VAD) actually finds speech, and mic lines that repeat what the call just said get dropped as echo. I tested it with speakers on at normal volume: no echo lines.",[10,89,90],{},"Then a bug I would never have guessed. ScreenCaptureKit, which captures the system audio, stops when the display goes to sleep. The default is two minutes. If you're just listening in a long call and not touching anything, the screen dims, sleeps, and the other side of the meeting quietly stops being recorded. Meetre now keeps the display awake while it records.",[22,92,94],{"id":93},"speed-as-a-consolation-prize","Speed, as a consolation prize",[10,96,97,98,100],{},"One thing in this whole saga went purely well. Diarization used to run on the CPU. Moving the ",[17,99,19],{}," pipeline onto Metal (MPS) and caching it per process took ten minutes of audio from about 275 seconds to about 23 on an M5 Pro. It falls back to the CPU if an operation fails on MPS. And the transcript now appears as soon as transcription is done, then updates in place once speakers and the summary are ready, so you're not staring at a spinner for the slow parts.",[10,102,103,104,111],{},"All of it is in the ",[105,106,110],"a",{"href":107,"rel":108},"https:\u002F\u002Fgithub.com\u002Fmaxlkatze\u002Fmeetre",[109],"nofollow","repo",", including the commit where I removed my own echo suppression two days after writing it. I wear headphones again anyway.",{"title":113,"searchDepth":114,"depth":114,"links":115},"",2,[116,117,118,119,120,121],{"id":24,"depth":114,"text":25},{"id":34,"depth":114,"text":35},{"id":54,"depth":114,"text":55},{"id":64,"depth":114,"text":65},{"id":83,"depth":114,"text":84},{"id":93,"depth":114,"text":94},"\u002Fimages\u002Fblog\u002Fmeetre\u002Fhud-live-transcript.png","2026-10-16","Labelling speakers in a call sounds like a solved problem until you take your headphones off. A week of echo, swapped names, a fix that muted me for my colleagues, and what Meetre does now.",false,"md","en",{},true,"\u002Fblog\u002Fen\u002Fmeetre-who-said-what",{"title":5,"description":124},"blog\u002Fen\u002Fmeetre-who-said-what",[134,135,136,137],"Meetre","Audio","Debugging","macOS","lJfeCgJk5i3AmyYcA-98RyvbcmH14oFarsO9-qf0QW4",1792165382440]