Skip to content

Commit ea3569a

Browse files
committed
Add README
Project overview, dev commands, architecture, BBC domain quirks worth knowing (T bit 7 polarity, PN=0 timing, 4-envelope limit), and a Future work section calling out channel 0 noise support and the periodic bass technique as the main missing capabilities.
1 parent 27b4c79 commit ea3569a

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# BBC Micro ENVELOPE Editor
2+
3+
A static web app for editing, visualising, and auditioning `ENVELOPE` parameters for the BBC Micro `SOUND` command.
4+
5+
**Live:** https://bitshifters.github.io/envelope-tool/
6+
7+
## Features
8+
9+
- Edit all 14 `ENVELOPE` parameters and the 4 `SOUND` parameters with live preview.
10+
- Editable BBC BASIC `ENVELOPE` and `SOUND` lines — paste an existing statement to populate the editor, or copy the formatted line for use in BASIC.
11+
- Visualisation of the resulting amplitude envelope (with A/D/S/R phase markers) and the absolute pitch over time.
12+
- Web Audio playback with a sweeping playhead synced to the audio clock.
13+
- 12 presets covering single-shot envelopes (Piano, Pluck, Bell, Pad, Bass, Drum, Laser) and looping pitch envelopes (Vibrato, Trill, Siren, Arpeggio, Wobble).
14+
- Shareable URL: every change is reflected in the URL bar via `?env=…&sound=…`, so copying the address reproduces the exact state.
15+
- "Run in BBC emulator" button that opens the current `ENVELOPE`/`SOUND` in [bbc.xania.org](https://bbc.xania.org/) (jsbeeb) for one-click A/B against the real BBC.
16+
17+
## Development
18+
19+
Stack: Vite + TypeScript (vanilla, no framework).
20+
21+
```sh
22+
npm install
23+
npm run dev # dev server with HMR
24+
npm run build # typecheck (tsc --noEmit) and produce dist/
25+
npm run preview # serve the built dist/ locally
26+
```
27+
28+
`vite.config.ts` sets `base: "./"` so the build works at either an org-page root or a project subpath. GitHub Pages deployment runs from `.github/workflows/pages.yml` on every push to `main`.
29+
30+
## Architecture
31+
32+
Three concerns are kept separate so each can be tested in isolation:
33+
34+
| Module | Responsibility |
35+
| --------------------- | ----------------------------------------------------------------------------------------------------------- |
36+
| `src/envelope.ts` | Pure model. The 14-parameter tuple, parse/format, and `expand()` into a per-centisecond `Sample[]` stream. |
37+
| `src/visualizer.ts` | Canvas rendering of the sample stream — amplitude and absolute pitch plots with phase markers and playhead. |
38+
| `src/audio.ts` | Web Audio engine that consumes the same sample stream and applies it to an oscillator + scheduled gain. |
39+
| `src/main.ts` | UI wiring: inputs, presets, URL state, transport. |
40+
| `src/presets.ts` | Bundled envelope + sound parameter sets for one-click loading. |
41+
42+
The visualiser and the audio engine consume the **same** sample array each render — what you see is exactly what you hear.
43+
44+
## BBC domain notes
45+
46+
The 14-parameter form is the source of truth. Anything in the UI must round-trip cleanly to and from `ENVELOPE N, T, PI1, PI2, PI3, PN1, PN2, PN3, AA, AD, AS, AR, ALA, ALD`.
47+
48+
A few non-obvious quirks (also documented in `CLAUDE.md`):
49+
50+
- `T` bit 7 polarity is inverted from intuition: `T = 1..127` (bit 7 **clear**) auto-repeats the pitch envelope; `T = 128..255` (bit 7 **set**) is single-sweep.
51+
- Pitch sections with `PN = 0` are not free — the OS hits `BEQ skipToNextChannel` after loading the empty section, so each empty section costs `T` cs of dead time. Loop wraps and non-empty section transitions are free.
52+
- The MOS allocates exactly **4** envelope slots (`N = 1..4`); higher numbers aren't usable.
53+
- Pitch is musically quantised to the BBC's own divider table (`pitchToHz()` in `src/envelope.ts`), not to equal temperament — higher octaves drift slightly sharp, matching the real machine.
54+
55+
## Future work
56+
57+
- **Channel 0 (noise).** This tool currently restricts `SOUND` channel to 1..3 and uses a square oscillator. Real BBC channel 0 is a separate noise generator with several modes selected by the pitch parameter (white / periodic at different rates, plus a mode that tracks channel 2's frequency).
58+
- **Periodic noise as bass.** When channel 0 is set to one of the periodic modes — particularly the mode that tracks channel 2 — the result is a coloured tone an octave or two below the reference. This is the classic BBC "periodic bass" trick used by many games. Supporting it requires emulating the SN76489's noise LFSR rather than substituting a square wave.
59+
- **Static amplitude.** Negative `SOUND` amplitude (-15..-1) selects a static volume bypassing the envelope. Currently disallowed in the UI.
60+
- **Stereo / multi-channel mixing.** Real BBC sequences usually involve simultaneous notes across multiple channels; this tool is single-note only.
61+
- **Authentic SN76489 timbre on tone channels.** The current square oscillator is a stand-in. A `PeriodicWave` or AudioWorklet implementation of the SN76489 tone generator would give a closer match.
62+
63+
## Credits
64+
65+
By Kieran Connell and Claude. Thanks to [Toby Lobster's MOS disassembly](https://tobylobster.github.io/mos/mos/index.html) — the authoritative reference used to nail down the BBC's pitch and envelope timing.

0 commit comments

Comments
 (0)