A real-time harmonic analyser that runs in the browser. It takes microphone input and shows the sound split into its component sine waves as it plays.
Live: https://paingheinhtet.com/wave-lab-analyzer/live.html. Click Power and allow the microphone. To run it on a synthetic signal without the microphone, open live.html#demo.
- Decomposition: each dominant frequency drawn as its own sine wave, labelled with its note (e.g.
440 Hz · A4) - Spectrum: all frequency components, with the strongest peaks marked
- Waveform and an X-Y phase plot (Lissajous figure)
- Fourier resynthesis: the detected sines summed back together (real DFT, phase-aligned) and overlaid on the input
- Harmonics: relative strength of H1 to H8
- Measurements: level and peak (dB), fundamental, period, wavelength in air, spectral centroid, zero-crossing rate
- Filters: low-pass, high-pass and band-pass, applied live
- Song ID: records a few seconds and identifies the track through the AudD API
- Sound classification: YAMNet running in the browser with TensorFlow.js (521 sound classes, no server)
Plain HTML, CSS and JavaScript with no build step. Audio comes from the Web Audio API: AnalyserNode provides the FFT for the spectrum, and a hand-written DFT provides phase for the resynthesis. Everything is drawn to <canvas> and runs client-side.
Browsers only allow microphone access from a secure context, so serve the folder rather than opening the file directly:
python3 -m http.server 8000
# open http://localhost:8000/live.htmlPress Power, play music, wait a few seconds: once the signal has been steady for four seconds the page records a clip and names the track. It then waits before the next attempt (150 s after a match, 240 s if the same song comes back, 45 s after no match) so a free AudD quota lasts. The AUTO ID button turns this off; the Identify button still works by hand.
Song ID uses the AudD API, which needs a token. Three ways to stop typing it:
- Once per device. A token pasted into the Song ID box is kept in the browser's storage and restored on the next visit. It is never committed.
- A private bookmark. Open
live.html?k=YOUR_TOKENonce; the page stores the token and removes it from the address bar before the URL reaches the history. Keep that bookmark to yourself, it carries the key. - The relay.
api/identify.jsis a small Vercel function that holds the token in the server-side variableAUDD_TOKEN, accepts the recorded clip from this page's own origins only, limits each address to six identifications per ten minutes, and forwards the clip to AudD. With it deployed, nobody needs a token. Deploy with the Vercel CLI from this folder, setAUDD_TOKENin the project settings, and put the function's address inID_PROXYat the top of the script inlive.html. A pasted token still bypasses the relay and uses that user's own quota. Keep the AudD account on its free tier or set a spending cap there.
wave_lab.py: a desktop version (matplotlib) that records from the microphone and shows the Fourier breakdown and a Laplace s-plane view.pip install numpy scipy matplotlib sounddevice soundfile python3 wave_lab.py devices # list microphones python3 wave_lab.py live --device 3wave_lab_colab.ipynb: a Colab notebook with a live spectrum, filters and a pitch-detection demo, generated bybuild_colab.py.
MIT
