← All projectsTry it right here Problem statement Solution Architecture Key features Challenges Lessons learned
2026
Swarabodha
A Carnatic music app that listens to your voice and identifies swaras and ragas in real time.
Learning to recognize swaras and ragas by ear is a slow, mentor-dependent process, and most Carnatic music theory tools are static reference charts rather than something you can sing into and get real feedback from.
Swarabodha listens to live microphone input or an uploaded audio clip, detects pitch in real time, maps each note to its exact swarasthana, sequences those into a swara pattern, and matches that pattern against a raga database for instant, browser-based feedback. A companion Python/PyQt desktop app, Swara Synth, reimplements the same detection and raga-matching engine natively for offline use.
A React, TypeScript, and Vite frontend captures microphone or uploaded audio (capped at 3 minutes) and runs autocorrelation-based F0 (pitch) estimation to extract fundamental frequency over time. Detected pitches are mapped through a 16-swarasthana model to identify each note, segmented into a swara sequence, and scored against a raga database of arohana, avarohana, and phrase patterns to surface likely raga matches. The desktop port mirrors this pipeline in Python, with the same swarasthana model and raga database design, running natively via PyQt instead of in a browser.
- Real-time pitch detection from live microphone input
- Exact swarasthana mapping across the 16-note Carnatic scale
- Swara sequencing from continuous pitch into discrete note patterns
- Raga recognition by matching swara sequences against arohana, avarohana, and phrase data
- Audio file upload and transcription, capped at 3 minutes
- A native Python/PyQt desktop port sharing the same detection and raga-matching engine
Keeping pitch detection from octave-jumping on sustained, pure tones, the autocorrelation detector had to be tuned to pick the first strong peak rather than the global maximum, verified against a synthetic S-R2-G3-P-D2-S test phrase.
Porting the same detection and raga-matching logic to a second, completely different runtime (Python/Qt versus TypeScript in the browser) was a good forcing function for surfacing assumptions baked into the original implementation.