Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Beatronome — Web & Terminal Metronome

Beatronome

A metronome that runs anywhere a browser does — and looks just as good in a terminal.
Sub-millisecond timing · click-to-edit accent patterns · works offline as a PWA

pwa web audio python textual license


✨ Features

  • BPM 30 – 300+ / − with press-and-hold acceleration, direct numeric input, or 60 / 80 / 100 / 120 / 140 shortcuts
  • Built-in presets — 2/4, 3/4, 4/4 (4/4 = strong / weak / medium / weak)
  • Custom patterns of 1 – 32 beats — tap each cell to cycle 4 intensities
  • 4 distinct click sounds█ 1500 Hz / ▄ 1000 Hz / ░ 700 Hz / · mute
  • Live beat highlight synced to the audio clock
  • Mobile-first PWA — add to home screen, wake-lock keeps the screen alive while practicing, Service Worker caches everything for offline use
  • Bonus terminal build — the same metronome as a Textual TUI

🚀 Quick start (web)

The whole web app is a single static folder — no build step, no dependencies. Three ways to run it:

Just open the file

Double-click web/index.html. Web Audio works from file://; only the Service Worker (offline cache) is unavailable. Everything else is identical.

Local server (recommended for phone use)

cd web
python -m http.server 8000
# desktop:  http://localhost:8000
# phone:    http://<your-LAN-ip>:8000   (same Wi-Fi)

Then on the phone, Add to Home Screen for the full-screen PWA experience.

Deploy

Drop web/ on any static host (GitHub Pages, Netlify, Vercel, Cloudflare Pages…). Serving over HTTPS unlocks full PWA install + offline cache on iOS.

WSL2 users: see web/README.md for mirrored-mode / netsh portproxy recipes if you want phones to hit a WSL-side server directly.


⌨️ Controls

action
Space start / stop
← → or + − BPM ± 1
↑ ↓ BPM ± 10
1 2 3 2/4 · 3/4 · 4/4
tap any beat cell cycle intensity (mute → weak → medium → strong)

🖥 Terminal build (optional)

Same model, same sounds, rendered with Textual. Useful when you're already in a shell.

sudo apt install -y libportaudio2     # Linux only; PortAudio for sounddevice
pip install -e .
beatronome                            # or: python -m beater
                ┌─────────┐
                │   120   │   BPM
                └─────────┘
            [ − ]  [120]  [ + ]

   Time:  [ 2/4 ]  [ 3/4 ]  [✓4/4]  [ Custom… ]

         ┌───┐  ┌───┐  ┌───┐  ┌───┐
         │ █ │  │ ░ │  │ ▄ │  │ ░ │
         └───┘  └───┘  └───┘  └───┘
           1      2      3      4

                [   ▶  START   ]

space start/stop · +/- BPM · 1/2/3 presets · c custom · q quit. No audio device? Falls back to terminal bell.


🧠 Design notes

Why a custom scheduler? setInterval and time.sleep accumulate drift on the order of tens of milliseconds — audible at 200 BPM. The web build uses the Chris-Wilson lookahead pattern: a 25 ms setInterval queues clicks 100 ms ahead against AudioContext.currentTime, so jitter is sample-accurate. The Python build does the equivalent with a time.perf_counter() accumulator on a daemon thread.

Why a PWA? Phones are where you actually want a metronome. Add-to-home-screen plus wake-lock plus offline caching means once you've loaded it, you don't need a network — or even a working web server — to use it again.

Pattern data model

const PRESETS = {
  "2/4": [3, 1],
  "3/4": [3, 1, 1],
  "4/4": [3, 1, 2, 1],   // strong, weak, medium, weak
};
// 0 = mute, 1 = weak, 2 = medium, 3 = strong

Custom patterns are any array of those, length 1 – 32. Tap cells to cycle.


📁 Layout

Beatronome/
├── web/                   # the main app — zero-build static PWA
│   ├── index.html
│   ├── app.js             # Web Audio scheduler, wake-lock, keyboard
│   ├── app.css            # mobile-first dark theme
│   ├── manifest.webmanifest
│   ├── sw.js              # cache-first service worker
│   ├── icon.svg
│   └── README.md          # hosting recipes (Windows / WSL2 / port-proxy)
├── beater/                # optional Python TUI build
│   ├── app.py             # Textual App, screen wiring
│   ├── engine.py          # threaded scheduler, perf_counter accumulator
│   ├── audio.py           # numpy click synthesis, sounddevice playback
│   ├── patterns.py        # Intensity enum + presets
│   ├── home_screen.py
│   ├── custom_screen.py
│   └── beater.tcss
├── pyproject.toml
└── banner.svg

📜 License

MIT. Use it, fork it, hand it to a friend who's learning to keep time.

About

Web PWA & terminal metronome with click-to-edit accent patterns. Sub-millisecond timing, offline-ready.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages