The recording pipeline had two bugs that combined to produce
buzzing/static in recorded audio:
1. NormalizeStereoFrame truncated incoming audio frames to
frameSize*AudioChannels samples. When the Opus decoder produced
20ms frames (1920 stereo samples) but the recorder used a 10ms
frameSize (960 samples), half the audio from every packet was
silently dropped.
2. The recorder's run() loop dequeued one fixed-length frame per
source per tick. After truncation, the remaining 10ms of each
20ms packet was gone, so every other tick produced silence.
This 50 Hz on/off pattern sounded like static.
Fixes:
- NormalizeStereoFrame no longer truncates; it only converts mono
to stereo and preserves all audio data
- RecordAudioFrame now accepts an explicit stereo flag from callers
instead of guessing from sample count (which failed for even-length
mono data like 480-sample mic frames)
- run() accumulates variable-length frames per source and consumes
them in fixed-size chunks, preserving any leftover for the next tick