UnigramDev/Unigram/voice-record-opus • a4413d4 • 6 files, +929/-141
Encode voice messages while they are recorded
A voice message was captured twice and encoded three times: a MediaFrameReader
already held every sample in memory to drive the blob, while LowLagMediaRecording
wrote the same audio to a WAV that was read back and re-encoded to Opus when the
message was sent.
OpusOutput.WriteFrame has been there the whole time and had no caller. The reader
now feeds it directly, so the file that lands on disk is already the file that
gets uploaded, and the duration is counted from the samples rather than taken
from MediaCaptureStopResult and truncated to a whole second.
The encoder is 48kHz mono and a frame source hands over whatever the endpoint
runs at, so this only applies when the format fits, or can be set to fit. It
falls back to the old path otherwise, because playing back at the wrong speed is
worse than transcoding.
Waveforms are sent now. They were computed and then dropped for Array.Empty,
which hid a bug in the accumulator: the bucket peak was never reset, so every
bucket held the running maximum of the whole recording and the waveform could
only climb.
The reader also had to stop dropping frames. Realtime acquisition and a 64ms
gate that returned before touching the buffer were fine for a blob and would
have cut holes in a recording, so it is Buffered now and only the level
notification is rate-limited.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#unigram
Post #20685
95