Browser Compatibility
Mankunku relies on modern Web APIs. This page documents compatibility requirements and known limitations.
Required APIs
| API | Used For | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|---|
| Web Audio API | All audio processing | 35+ | 25+ | 14.1+ | 79+ |
getUserMedia | Microphone capture | 53+ | 36+ | 14.1+ | 79+ |
| AudioWorklet | Onset detection | 66+ | 76+ | 14.1+ | 79+ |
Permissions.query | Mic permission check | 43+ | 46+ | 16+ | 79+ |
localStorage | Settings, progress | All | All | All | All |
CacheStorage | SoundFont caching | 40+ | 41+ | 11.1+ | 79+ |
requestAnimationFrame | Pitch detection loop | 10+ | 23+ | 6.1+ | 12+ |
| CSS Custom Properties | Theming | 49+ | 31+ | 9.1+ | 15+ |
| ES2022+ | Async/await, modules | 89+ | 89+ | 15+ | 89+ |
Minimum Browser Versions
| Browser | Minimum Version | Limiting Factor |
|---|---|---|
| Chrome | 66+ | AudioWorklet |
| Firefox | 76+ | AudioWorklet |
| Safari | 14.1+ | AudioWorklet, getUserMedia |
| Edge | 79+ | Chromium-based |
Not supported: Internet Explorer, Opera Mini, older mobile browsers without AudioWorklet.
Mobile Considerations
iOS Safari
- AudioContext resume — iOS Safari suspends the AudioContext until a user gesture. Mankunku handles this via
Tone.start()called from the first tap. - getUserMedia — Requires HTTPS. Works on iOS 14.3+ for Safari.
- Screen lock — Audio may stop when the screen locks. Users should keep the screen active during practice.
- Low-latency mode — iOS Safari has higher audio latency than desktop browsers. The latency correction in the scorer absorbs most of this.
Android Chrome
- AutoPlay policy — Same as desktop Chrome: user gesture required to start AudioContext.
- getUserMedia — Works reliably on Chrome for Android.
- Performance — Lower-end devices may struggle with 60fps pitch detection. The
requestAnimationFrameloop naturally adapts to device capability.
PWA Support
Mankunku is configured as a Progressive Web App via @vite-pwa/sveltekit:
- Installable — Can be added to home screen on mobile and desktop
- Offline-capable — Static assets are cached via service worker
- Icons — App icons in
static/icons/ - Manifest — Auto-generated by the PWA plugin
Note: Microphone access requires HTTPS in all browsers. Development via localhost is exempt.
Known Limitations
Permissions API
The navigator.permissions.query({ name: 'microphone' }) API:
- Not supported in all browsers (gracefully falls back to
'prompt') - On macOS, may report
'denied'even when the user hasn't been prompted (browser-level permission not yet granted). Mankunku treats'denied'as'prompt'conservatively.
AudioWorklet Module Loading
The onset detector loads its worklet via:
const workletUrl = new URL('./onset-worklet.ts', import.meta.url);
await context.audioWorklet.addModule(workletUrl);
This relies on Vite transforming the TypeScript worklet file into a loadable module. In production builds, Vite handles this correctly. In some development configurations with HMR, the worklet URL may need special handling.
SoundFont Loading
First instrument load requires downloading a ~2MB SoundFont file. This is cached via CacheStorage (not localStorage) for subsequent visits. A loading indicator shows during this process.
Pitch Detection Accuracy
- Polyphonic signals — The McLeod Pitch Method is designed for monophonic instruments. Background noise, multiple instruments, or harmonics from certain embouchures may cause detection errors.
- Low notes — Notes below ~80Hz require longer analysis windows and may have lower clarity scores.
- Very high notes — Above ~1200Hz, harmonics and overtones can cause octave errors.
Audio Latency
Total system latency (mic → detection → display) is typically 50–150ms, depending on:
- AudioContext buffer size (4096 samples ≈ 85ms at 48kHz)
requestAnimationFrameinterval (~16ms)- Browser audio pipeline latency
The scoring system's latency correction absorbs constant delays, so latency primarily affects real-time visual feedback rather than scoring accuracy.
HTTPS Requirement
Microphone access (getUserMedia) requires a secure context:
https://in productionhttp://localhostin development (exempt)http://127.0.0.1in development (exempt)
Deploy behind HTTPS for production use.