Five real instruments, synthesized note by note in your browser. No samples, no installs, no plugins — just the Web Audio API and the physics of each instrument.
▶ Play now: moshejs.github.io/digital-instruments
![]() |
![]() |
![]() |
| No. 01 — Steelpan Strike 25 chrome pads in the authentic circle-of-fifths layout. |
No. 02 — Theremin "Aetherwave" Play without touching — hover, or tilt and shake your phone. |
No. 03 — Kalimba Tap or sweep 17 steel tines; read real kalimba number tabs. |
![]() |
![]() |
|
| No. 04 — Glass Harp Circle a rim to make a glass sing; faster is louder, many fingers make chords. |
No. 05 — Lever Harp Pluck or drag for glissandos; sharping levers flip themselves for each song. |
| How you play | How it sounds | |
|---|---|---|
| Steelpan | Click, tap or a piano-style keyboard | Seven additive partials — a hand-detuned octave and twelfth — over a band-passed noise strike |
| Theremin | Hover for pitch and volume; on phones, roll / tilt / shake (gyroscope + accelerometer) | Two crossfaded oscillators, a vibrato LFO and portamento glide, with a live oscilloscope |
| Kalimba | Tap or sweep tines; keys 1–7, Q–U, A S D |
Clamped-tine cantilever modes at 1 : 6.27 : 17.55, a thumb click and a wooden-box resonance |
| Glass Harp | Press and circle a rim (speed = loudness), multi-touch chords, or hold keys | Glass bending modes with a detuned twin for shimmer, plus band-passed friction noise |
| Lever Harp | Pluck, drag across to strum, keys 1–7, Q–U, I; Shift+key flips a lever |
Karplus–Strong plucked strings with a soundboard resonance; E♭ tuning with sharping levers |
- 🎵 Fifteen public-domain songs — Twinkle Twinkle, Mary Had a Little Lamb, Ode to Joy, When the Saints Go Marching In, Amazing Grace, Oh! Susanna, Greensleeves, Scarborough Fair, Londonderry Air (Danny Boy), Jingle Bells, Silent Night, We Wish You a Merry Christmas, Auld Lang Syne, Happy Birthday and Frère Jacques.
- ▶ Listen plays the tune; ◎ Play Along lights the next pad, tine, glass or string (or sweeps a target across the theremin and scores how long you stay on pitch).
- 🔗 A page for every song on every instrument —
/kalimba/ode-to-joy/opens the kalimba with the song ready, followed by a written lesson with every note in that instrument's notation (kalimba tabs, flats on the pan, lever settings on the harp). Old?song=links still work. - Each instrument only offers songs it can really play: the C-major kalimba explains which ones need sharps or flats. The harp sets its levers for each song's key and flips them mid-song when a melody needs it (Greensleeves uses both G and G♯).
Every melody was transcribed, then independently re-derived note by note by a second pass that corrected errors before they shipped.
Requires Node.js 22.12 or newer (.nvmrc pins 24).
npm install
npm run dev # http://localhost:4321/digital-instruments/
npm run check # strict TypeScript + Astro diagnostics
npm test # Vitest unit tests
npm run build # static site in dist/
npm run icons # regenerate favicons, app icons and social cardssrc/
data/ songs.ts (shared songbook) · instruments.ts (catalogue, structured data) · availability.ts (which songs fit which instrument) · song-pages.ts (song pages: notation, copy, JSON-LD)
lib/ music.ts · keyboard.ts · steelpan-layout.ts · theremin-field.ts · kalimba-layout.ts · glass-layout.ts · harp.ts (levers + geometry) · audio.ts · site.ts
scripts/ one engine per instrument · shared/guide-player.ts (Listen / Play Along) · shared/song-ui.ts
instruments/ one component per instrument: its header, stage, coach, songs and settings
components/ SiteNav · CoachBand · SongLibrary · SettingsCard · SongSheet (the written lesson) · InstrumentFooter
layouts/ Base.astro — SEO, Open Graph, Twitter cards, JSON-LD, icons · InstrumentPage.astro — shared instrument page shell
pages/ index · <instrument>/index · <instrument>/[song] · llms.txt · 404
styles/ instrument.css (shared shell + panel, themed by tokens) · one stylesheet per instrument
scripts/ generate-images.mjs — renders every icon and social card (including one per song page) from the same layout code
tests/ note math, songbook, layouts, availability and harp lever logic
- Add its layout/logic to
src/lib/and its slug toInstrumentSlugandcanPlayinsrc/data/availability.ts. - Add catalogue metadata to
src/data/instruments.ts. - Write an engine in
src/scripts/and callmountGuide(slug, host, copy)— theGuideHostonly needsunlock,performandshowTarget. - Create
src/instruments/<Name>.astro(header, stage,CoachBand,SongLibrary,SettingsCard) and a stylesheet that sets the shared colour tokens, thensrc/pages/<slug>/index.astroand[song].astrothat wrap it inInstrumentPage. Add its lesson copy toCOPYinsrc/data/song-pages.ts. - Draw its favicon and card in
scripts/generate-images.mjs, thennpm run icons.
- 72 song pages that search engines can read without JavaScript, each with its own title, description, canonical URL and 1200×630 card (
public/og/songs/). Song links are plain<a>tags, in the footer of every instrument page and in the home page songbook. - Open Graph and Twitter cards on every page; schema.org JSON-LD (
WebSite,ItemList,WebApplication,LearningResource+MusicComposition,BreadcrumbList). - A sitemap with
lastmod(taken from the last commit),robots.txt, and/llms.txtfor AI assistants. - Per-instrument SVG favicons, PNG/ICO fallbacks, an Apple touch icon and an installable web manifest with shortcuts to each instrument.
Pushing to main runs .github/workflows/deploy.yml: type-check → test → build → deploy to GitHub Pages. Pull requests run the same checks without deploying.
MIT © 2026 Moshe Malka. All melodies are in the public domain.





