A browser-based theremin synthesizer controlled by hand gestures using webcam and computer vision. Play music with your hands in the air! Experience the magic of the theremin - the world's first electronic musical instrument - in your browser.
- ✨ Features
- 🎯 Demo
- 🚀 Quick Start
- 🎮 How to Play
- 🛠️ Development
- 📚 Documentation
- 🎵 Performance
- 🔧 Configuration
- 🎯 Tips for Best Performance
- 🐛 Troubleshooting
- 🤝 Contributing
- 📝 License
- 🙏 Acknowledgments
- 🔗 Links
- Gesture Control: Use right hand for pitch, left hand for volume
- Real-time Audio: Professional Web Audio API synthesis with multiple waveforms
- Visual Feedback: Live frequency, volume, and FPS display with pitch visualization
- Customizable Settings: Adjustable pitch/volume ranges, smoothing, and presets
- Zero Installation: Runs entirely in your browser, no plugins required
- Responsive Design: Works on desktop and tablet devices
- Performance Monitoring: Built-in FPS tracking and optimization
- Multiple Waveforms: Sine, sawtooth, square, and triangle waves
- Smoothing Controls: Adjustable gesture smoothing for clean performance
- Preset System: Quick configurations for different playing styles
- Hold Function: Freeze current note with spacebar
- Settings Panel: Advanced controls accessible via keyboard shortcut
- Error Handling: Graceful fallbacks for camera and audio issues
- Intuitive Interface: Clean, modern design with clear visual feedback
- Accessibility: Keyboard shortcuts and screen reader support
- Mobile Friendly: Responsive design for tablet use
- Performance Warnings: Visual indicators for low FPS or tracking issues
Experience the Web Theremin live:
- Live Demo: https://web-theremin.vercel.app (Coming Soon)
- Video Demo: YouTube Demo (Coming Soon)
- Immediate Response: Low-latency hand tracking and audio synthesis
- Musical Expression: Full control over pitch and volume dynamics
- Visual Learning: Real-time frequency and volume displays
- Creative Freedom: Experiment with different waveforms and settings
- Browser: Chrome 122+, Edge 122+, or Firefox 124+
- Webcam: Any webcam for hand tracking (720p+ recommended)
- Node.js: 16+ for development (optional for users)
- Audio Output: Speakers or headphones
- Visit the live demo at https://web-theremin.vercel.app
- Allow camera access when prompted
- Click "Start Theremin" and begin playing!
-
Clone the repository:
git clone https://github.com/d00merog/web-theremin.git cd web-theremin -
Install dependencies:
npm install
-
Start development server:
npm run dev
-
Open in browser: Navigate to
http://localhost:5173 -
Allow camera access when prompted
-
Click "Start Theremin" and start playing!
- Right Hand: Move up/down to control pitch (frequency)
- Left Hand: Move up/down to control volume (amplitude)
- Both Hands: Use together for expressive performance
Camera View:
┌─────────────────┐
│ 🖐️ Right │ ← Pitch Control
│ Hand │
│ │
│ 🖐️ Left │ ← Volume Control
│ Hand │
└─────────────────┘
| Key | Action | Description |
|---|---|---|
| Fist Gesture | Hold current note | Freeze pitch and volume |
| H | Toggle settings panel | Access advanced controls |
| Escape | Stop theremin | Return to start screen |
| R | Reset settings | Return to default configuration |
Press H to access advanced controls:
- Min Freq: 32-220 Hz (C1-A3)
- Max Freq: 440-2000 Hz (A4-C7)
- Default: C2 (65.4 Hz) to C6 (1047 Hz)
- Min Vol: -60 to -10 dB (quietest level)
- Max Vol: -20 to 0 dB (loudest level)
- Default: -40 dB to -6 dB
- Sine: Smooth, pure tone (default)
- Sawtooth: Bright, buzzy sound
- Square: Digital, hollow sound
- Triangle: Mellow, flute-like tone
- 0.05: Very responsive, may be jittery
- 0.2: Balanced (default)
- 0.5: Very smooth, less responsive
| Preset | Frequency Range | Waveform | Use Case |
|---|---|---|---|
| Default | C2-C6 | Sine | General playing |
| Deep | C1-C4 | Triangle | Bass tones |
| Bright | C3-C7 | Sawtooth | Lead melodies |
| Classical | A2-A5 | Sine | Traditional theremin |
| Experimental | C0-C8 | Square | Electronic music |
web-theremin/
├── src/
│ ├── lib/
│ │ ├── theremin.ts # Audio engine using Tone.js
│ │ └── tracking.ts # MediaPipe hand tracking
│ ├── components/
│ │ ├── overlay.ts # HUD and visual feedback
│ │ └── settings.ts # Settings panel
│ ├── test/
│ │ ├── theremin.test.ts # Unit tests for audio engine
│ │ └── overlay.test.ts # UI component tests
│ └── main.ts # Application entry point
├── public/
│ ├── index.html # Main HTML file
│ └── favicon.ico # Site icon
├── docs/ # Documentation
├── dist/ # Production build
├── package.json # Dependencies and scripts
├── vite.config.ts # Build configuration
├── tailwind.config.js # CSS framework config
├── tsconfig.json # TypeScript configuration
└── README.md # This file
| Technology | Version | Purpose |
|---|---|---|
| TypeScript | 5.2+ | Type-safe JavaScript |
| Vite | 4.5+ | Fast build tool and dev server |
| Tone.js | 14.7+ | Web Audio API wrapper |
| MediaPipe | 0.10+ | Hand tracking and computer vision |
| WebGPU | 1.0+ | GPU-accelerated graphics and computation |
| Tailwind CSS | 3.4+ | Utility-first CSS framework |
| Vitest | 0.34+ | Unit testing framework |
| PostCSS | 8.4+ | CSS processing |
# Development
npm run dev # Start dev server with hot reload
npm run build # Build for production
npm run preview # Preview production build
# Testing
npm run test # Run tests in watch mode
npm run test:run # Run tests once
npm run test:ui # Open test UI
# Quality Assurance
npm run lint # Check code style
npm run type-check # TypeScript checking
npm run format # Format code with Prettier- Fork and clone the repository
- Install dependencies with
npm install - Start development with
npm run dev - Write tests for new features
- Run tests with
npm run test - Build for production with
npm run build - Submit a pull request
- TypeScript: Strict mode enabled
- ESLint: Code style enforcement
- Prettier: Code formatting
- Vitest: Unit and integration tests
- Bundle Size: Keep under 110KB gzipped
- Update documentation for new features
- Follow the existing code style
type(scope): description
[optional body]
[optional footer]
Examples:
feat(audio): add new waveform optionfix(tracking): resolve hand detection issuesdocs(readme): update installation instructions
This project follows the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code.
- Usage Guide: Comprehensive user manual
- Troubleshooting: Common issues and solutions
- Performance Guide: Optimization tips
- API Reference: Technical documentation
- Architecture: System design overview
- Contributing: Development guidelines
- Testing: Test strategy and examples
- Getting Started: Basic setup and playing
- Advanced Techniques: Performance tips
- Development Setup: Local development
| Metric | Target | Current |
|---|---|---|
| Latency | ≤120ms end-to-end (p95) | ~100ms |
| Frame Rate | ≥30 FPS hand tracking | 30-60 FPS |
| Bundle Size | ≤103KB gzipped | ~98KB |
| Memory Usage | ≤50MB | ~35MB |
| CPU Usage | ≤15% on modern hardware | ~10% |
| Feature | Chrome | Edge | Firefox | Safari |
|---|---|---|---|---|
| Web Audio API | ✅ 122+ | ✅ 122+ | ✅ 124+ | |
| MediaPipe Hands | ✅ | ✅ | ✅ | ❌ |
| getUserMedia | ✅ | ✅ | ✅ | ✅ |
| Canvas API | ✅ | ✅ | ✅ | ✅ |
| ES6 Modules | ✅ | ✅ | ✅ | ✅ |
- Exponential Smoothing: Reduces gesture jitter
- Performance Monitoring: Visual FPS warnings
- Efficient Rendering: Canvas-based hand visualization
- Memory Management: Proper cleanup of audio resources
- Lazy Loading: Load MediaPipe only when needed
- Bundle Splitting: Separate vendor and app code
new ThereminEngine({
minFreq: 65.41, // Minimum frequency (Hz) - C2
maxFreq: 1046.50, // Maximum frequency (Hz) - C6
minVol: -40, // Minimum volume (dB)
maxVol: -6, // Maximum volume (dB)
waveform: 'sine', // Oscillator waveform
smoothing: 0.2, // EMA smoothing factor
attack: 0.1, // Volume attack time (seconds)
release: 0.3, // Volume release time (seconds)
});HandLandmarker.createFromOptions(vision, {
runningMode: 'VIDEO',
numHands: 2, // Track up to 2 hands
minHandDetectionConfidence: 0.5, // Minimum detection confidence
minHandPresenceConfidence: 0.5, // Minimum presence confidence
minTrackingConfidence: 0.5, // Minimum tracking confidence
});// For low-end devices
const lowEndConfig = {
smoothing: 0.3, // More smoothing
minFreq: 110, // Higher minimum frequency
maxFreq: 880, // Lower maximum frequency
frameRate: 15, // Lower frame rate
};
// For high-end devices
const highEndConfig = {
smoothing: 0.1, // Less smoothing
minFreq: 32, // Lower minimum frequency
maxFreq: 2000, // Higher maximum frequency
frameRate: 60, // Higher frame rate
};- Lighting: Use good lighting, avoid backlighting
- Background: Plain background improves tracking
- Distance: Sit 2-3 feet from camera
- Position: Center hands in camera view
- Resolution: 720p or higher recommended
- Smooth Movements: Avoid jerky motions for clean sound
- Hand Separation: Keep hands apart for clear tracking
- Finger Position: Extend fingers for better detection
- Practice: Start with slow movements, build up speed
- Breathing: Use natural breathing rhythm for expression
- Scales: Practice major and minor scales
- Intervals: Work on octaves, fifths, fourths
- Vibrato: Small oscillating hand movements
- Glissando: Smooth pitch slides
- Dynamics: Coordinate both hands for expression
- Browser: Use Chrome or Edge for best performance
- Tabs: Close unnecessary browser tabs
- Applications: Close other audio/video applications
- Hardware: Use dedicated graphics if available
- Network: Wired connection for web-based versions
Camera not working:
- Check browser permissions
- Refresh page and try again
- Ensure camera isn't used by another app
- Try different browser
No hand detection:
- Improve lighting conditions
- Move closer to camera
- Check hand position in frame
- Try different hand gestures
Low FPS (red warning):
- Close other browser tabs
- Check system resources
- Try lower camera resolution
- Restart browser
Audio latency:
- Use Chrome/Edge for best performance
- Close unnecessary applications
- Use wired headphones
- Check audio drivers
No sound:
- Check if theremin is started
- Verify browser audio isn't muted
- Try different waveform settings
- Check hand tracking is working
Distortion or clicks:
- Lower max volume setting
- Increase smoothing
- Check audio hardware
- Try different browser
| Browser | Known Issues | Solutions |
|---|---|---|
| Chrome | None | Best performance |
| Edge | None | Excellent performance |
| Firefox | Occasional audio glitches | Update to latest version |
| Safari | No MediaPipe support | Use Chrome/Edge |
| Mobile | Limited performance | Use desktop version |
The application includes built-in diagnostics:
- FPS Counter: Shows hand tracking frame rate
- Status Indicator: Current application state
- Error Messages: Clear feedback for issues
- Performance Warnings: Visual alerts for problems
We welcome contributions from the community! Here's how you can help:
- 🐛 Bug Reports: Report issues with detailed information
- 💡 Feature Requests: Suggest new features or improvements
- 📝 Documentation: Improve docs and add examples
- 🎨 UI/UX: Enhance the user interface
- ⚡ Performance: Optimize code and reduce bundle size
- 🧪 Testing: Add tests and improve test coverage
- 🌐 Localization: Add translations for different languages
- Fork the repository
- Clone your fork:
git clone https://github.com/your-username/web-theremin.git - Install dependencies:
npm install - Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Test your changes:
npm run test - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
- Write tests for new features
- Follow TypeScript strict mode
- Use semantic commit messages
- Ensure bundle size stays under 110KB
- Update documentation for new features
- Follow the existing code style
type(scope): description
[optional body]
[optional footer]
Examples:
feat(audio): add new waveform optionfix(tracking): resolve hand detection issuesdocs(readme): update installation instructions
This project follows the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code.
This project is licensed under the MIT License - see the LICENSE file for details.
- Commercial Use: ✅ Allowed
- Modification: ✅ Allowed
- Distribution: ✅ Allowed
- Private Use: ✅ Allowed
- Liability: ❌ No warranty provided
- Warranty: ❌ No warranty provided
- MediaPipe team for hand tracking technology
- Tone.js community for Web Audio abstractions
- Theremin inventors for the original inspiration
- Web Audio API specification contributors
- Vite for fast development and building
- Tailwind CSS for utility-first styling
- Vitest for modern testing framework
- TypeScript for type safety
- Early testers and feedback providers
- Music educators for educational insights
- Theremin enthusiasts for historical context
- Web developers for technical guidance
- Léon Theremin (1896-1993) - Inventor of the theremin
- Clara Rockmore (1911-1998) - Virtuoso theremin performer
- Robert Moog (1934-2005) - Theremin kit manufacturer
- Live Demo: https://web-theremin.vercel.app (Coming Soon)
- Repository: https://github.com/d00merog/web-theremin
- Issues: https://github.com/d00merog/web-theremin/issues
- Discussions: https://github.com/d00merog/web-theremin/discussions
- Usage Guide: USAGE.md
- API Reference: docs/api.md
- Contributing: CONTRIBUTING.md
- Code of Conduct: CODE_OF_CONDUCT.md
- Theremin History: Wikipedia
- MediaPipe: Google AI
- Tone.js: Web Audio Framework
- Web Audio API: MDN Documentation
- Twitter: @web_theremin
- Discord: Community Server
🎵 Made with
Experience the magic of the theremin - the world's first electronic musical instrument - in your browser. No installation required, just pure musical expression through hand gestures.