DevTools Logo
All posts

Beats, Canvas Exports, BPM Taps, Waveforms & Avro

September 5, 2026 · DevTools

audio
canvas
bpm
svg
avro

Focus sound, animation exports, tempo measurement, waveform art, and event typing all run in the browser tab now. This guide covers the Binaural Beats Synthesizer, Canvas to WebM & GIF Exporter, Audio BPM Tap Detector, Audio Waveform to SVG, and Avro Schema to TypeScript.

Beats and noise, synthesized deterministically

A binaural beat is pure subtraction: play 220 Hz in one ear and 230 Hz in the other and the brain perceives a 10 Hz pulse, which calculateBeatFrequency computes as the absolute difference. Five presets sit on a shared 220 Hz carrier — Delta at 2 Hz for deep rest, Theta at 6 Hz for meditation, Alpha at 10 Hz for calm focus, Beta at 18 Hz for alert concentration, and Gamma at 40 Hz for high-level cognition.

generateNoise adds seeded white, pink, or brown noise behind the tones, so the same seed reproduces the same bed every session, and generateBinauralSamples renders the full mix to floating-point samples for preview. Everything is computed, not streamed — start with Alpha at low volume and treat Gamma as an experiment.

Export canvas animation without a server round-trip

createFramePlan turns an fps value and a render callback into timestamped frames, and from there two export paths diverge. WebM goes through the browser MediaRecorder with negotiated MIME types — VP9 preferred, then VP8, then plain WebM — probed by selectWebmMimeType so unsupported codecs fail fast. GIF export needs no browser support: a deterministic GIF89a encoder maps pixels through a fixed palette (rgbaToIndexed, encodeGif), with frame delays derived from fps and looping optional.

Rule of thumb: WebM for smooth captures, GIF for short loops that must play inline everywhere. Keep GIFs to a few seconds at modest resolution — per-frame bitmaps grow fast — and preview the frame plan timing before encoding.

Measure tempo, draw waveforms, type your event streams

analyzeTaps works on the median interval and filters outliers with a median-absolute-deviation gate (threshold 3, BPM clamps applied), so one early tap cannot skew the reading. detectOnsets covers the microphone path: an energy-rise detector over 1024-sample frames with a 512-sample hop reports onsets, and bpmFromOnsets converts them to tempo. Tap when you have fingers, record when you have a loop.

Audio Waveform to SVG condenses samples into 64 blobs via analyzeWaveform, then generateWaveformPath draws mirrored bars, a line, or a filled area, wrapped by generateWaveformSvg in a labeled SVG. Paste the path into any design tool — ideal for podcast players that should not ship image assets.

compileAvroSchema emits TypeScript declarations and JSON Schema together. Records become interfaces, enums become string unions, fixed types become sized byte arrays, logical types survive as annotations, and named types are deduplicated through a declaration map with JSON Schema references:

export interface ClickEvent {
  userId: string;
  occurredAt: number; /* logicalType: timestamp-millis is noted in a comment */
  variant: string | undefined;
}
export type ExperimentArm = "control" | "treatment";

Empty unions and malformed enums or fixed sizes throw with the offending name, so mistakes surface at authoring time rather than in a midnight pipeline failure.

Try Them