Spectral masking analysis · Django + NumPy
SomaSonic answers that per frequency band, per time window — from the raw samples, not from a listening session. Upload a narration stem and the bed that plays underneath it, and it returns the map of exactly where the two are fighting.
2 min 22 s · captions included
Open the live app Download the screencast
The live instance is a public sandbox with a finished report already loaded — sign in with the demo account to look around, or register to analyse your own stems. Stems are capped at five minutes because anyone can reach it.
Four states of the running application
Client decimation → NumPy STFT → canvas
OfflineAudioContext downmixes to mono and resamples to 16 kHz Int16 PCM before anything is sent. That is what keeps the backend down to two dependencies — no ffmpeg, no librosa, no codec binaries in the deploy.np.frombuffer(..., '<i2') and derives duration by counting samples, so a file lying in its header cannot shift the timeline.N=1024, hop 512 — 31.25 frames per second. A three-minute track becomes 5,624 analysable frames.HEADROOM_DB = −6.0 threshold.fillRect in about 25 ms. As DOM elements it would have frozen the render tree.It came from a real failure
I run an autonomous pipeline that renders long-form documentary films — generated narration over a generated music bed. Its worst recurring defect was never a crash: it was a finished film where the bed sat on top of the voice, and nothing in the system could see it, because loudness targets are met by a mix that is still unintelligible. A single number for the whole track cannot find a clash that lives in one band for seven seconds.
SomaSonic is that missing measurement built as its own tool: not “is this loud enough”, but where, and for how long, is the bed inside the voice's headroom. The run shown above is real material from that pipeline — a Ngorongoro episode's narration against its own music bed. It scores 48%, with 27.4 seconds of speech contested, almost all of it under 312 Hz.
Academic honesty. SomaSonic is my capstone for HarvardX CS50W (Web Programming with Python and JavaScript), submitted in September 2026 and currently in grading — not a completed credential.
The source repository stays private under CS50's policy on publishing coursework. This page shows the interface and the design decisions; it does not distribute the code. Happy to walk through the implementation live.