Skip to content

Add Beat Studio: a browser-based music workstation - #1

Merged
ibrahimweng merged 2 commits into
mainfrom
claude/project-build-g0w7oz
Aug 18, 2026
Merged

Add Beat Studio: a browser-based music workstation#1
ibrahimweng merged 2 commits into
mainfrom
claude/project-build-g0w7oz

Conversation

@ibrahimweng

@ibrahimweng ibrahimweng commented Aug 18, 2026

Copy link
Copy Markdown
Owner

This PR adds Beat Studio, a complete web-based music production application built with TypeScript and the Web Audio API. It's a fully-featured instrument with synthesized sounds, a step sequencer, and recording/export capabilities.

Overview

Beat Studio is a self-contained music workstation that runs entirely in the browser with no external audio files or server dependencies. It features three playable instruments (drums, piano, and guitar), a 16/32-step sequencer, recording with waveform visualization, and export to WAV, MP3, or MIDI formats.

Key Features

  • Three Instruments: Synthesized drum kit with 13 pads, 88-key piano, and 6-string steel guitar
  • Step Sequencer: 16 or 32-step pattern sequencer with 8 drum lanes and pattern banking (A/B/C/D)
  • Recording: Real-time recording with automatic take management and waveform peak visualization
  • Export: Save recordings as WAV or MP3, or export patterns as MIDI files
  • Audio Engine: Pure Web Audio API synthesis with no external sample dependencies (optional General MIDI samples via CDN)
  • Transport Controls: Play/stop, tempo control (40-220 BPM), metronome with beat/sixteenth subdivisions
  • Mixer: Master volume, 3-band EQ, and reverb and tilt controls
  • Theming: Dark-mode UI with customizable accent colors and ground finishes

Implementation Details

  • Architecture: Session-based state management with reactive UI views that subscribe to store changes
  • Audio: Modular voice synthesis (noise, drums, piano, pluck) with transport-based scheduling and lookahead
  • UI: DOM-based views (no framework) with efficient event delegation and minimal redraws
  • Persistence: LocalStorage-based save/load for patterns and settings
  • Export: Custom encoders for WAV (PCM), MP3 (via lamejs), and MIDI (SMF format)
  • Design: Matches Toolcraft design system with CSS custom properties for theming

File Structure

  • src/audio/: Engine, voices, transport, and recorder
  • src/ui/: View components (drums, keys, guitar, sequencer, mixer, inspector)
  • src/export/: WAV, MP3, and MIDI encoders
  • src/styles/: Design tokens, layout, controls, and instrument-specific styles
  • design/: Original design files and Toolcraft sync notes

The app can be built with npm run build to generate static files suitable for any web host.


Corrections to the description above

Four figures in the original description did not match the code, and have been corrected:

Was Now Source
drum kit with 8 pads 13 pads src/ui/drums.ts, the PADS table
sequencer with 4 drum lanes 8 lanes src/constants.ts, LANES (4 is the bank count)
tempo 60-180 BPM 40-220 BPM src/constants.ts, BPM_MIN and BPM_MAX
per-instrument gain 3-band EQ, reverb and tilt src/types.ts, SliderName and KnobName

There is no per-instrument gain control. All instruments share one bus, and the user-facing controls are master volume, three EQ bands, a reverb send and a tilt knob.

Verification

The built app was driven end to end in Chromium. All checks pass with no console errors:

  • 13 pads, 52 white and 36 black keys, 15 frets by 6 strings, 8 lanes by 32 step slots
  • A recorded take of 1.9s with 16 logged notes and a 96-bar waveform
  • WAV export, 338,728 bytes, valid RIFF/WAVE header
  • MP3 export, 36,989 bytes, valid MPEG frame sync
  • MIDI export, valid MThd header
  • Patterns and tempo survive a reload, and the four banks stay independent
  • No horizontal overflow down to 860px wide

CI runs the type check and the build on Node 20 and Node 22. Both were verified locally by installing each version and running the workflow's exact steps.

Fixes to problems in the original design prototype

  • Count-in was a switch that nothing read. It now plays a bar of clicks before recording starts.
  • A black piano key sat inside its white neighbour and both handlers fired, so one click sounded two notes.
  • The recording readout covered the header text on the piano and guitar screens.
  • The piano keybed pushed the shell wider and shrank the inspector panel from 292px to 250px.

https://claude.ai/code/session_01PZUNgxTt93bKkqEiQ5P5ae

claude added 2 commits August 18, 2026 22:41
Builds the Beat Studio design prototype into a real application in
beat-studio/. The prototype ran on a template language interpreted at
runtime by a proprietary runtime; this is a rewrite in TypeScript with
Vite, and has no runtime dependency on the design tool.

What it does:
- Drum kit with 13 synthesised pads, an 88 key piano and a steel guitar
- Step sequencer with 8 lanes, 16 or 32 steps and 4 pattern banks
- Transport with tempo, metronome, count-in and take length
- Recording to takes, with waveform overview and layering
- Export to WAV, MP3 and MIDI

How it is put together:
- audio/ holds the graph, synthesis, step clock and recorder, and never
  touches the page
- ui/ holds one file per part of the interface and never talks to the
  audio engine directly
- session.ts is the only place where state, sound and timing meet
- Notes are scheduled ahead of the audio clock so timing does not drift

Three fixes to problems in the prototype:
- Count-in was a switch that nothing read. It now plays a bar of clicks
  before a recording starts.
- A black piano key sat inside its white neighbour and both handlers
  fired, so one click sounded two notes.
- The recording readout covered the header text on the piano and guitar
  screens, and the piano keybed pushed the shell wider and shrank the
  inspector panel.

The sampled instruments are optional and load from a third party server.
Add ?samples=off to stay on the built-in voices and contact nothing.

The original design files are kept in beat-studio/design/ for reference.
The Flutter app at the top level of the repository is untouched.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PZUNgxTt93bKkqEiQ5P5ae
Runs the type check and the build on every push and pull request that
changes beat-studio/. The Flutter app at the top level has no CI and the
workflow ignores it.

The matrix covers Node 20 and Node 22. Both were verified by installing
each version and running the exact steps the workflow runs. On Node 20,
npm correctly skips @napi-rs/lzma-linux-x64-gnu, an optional dependency
of rollup that requires Node 22.20 or newer, and the build still passes.

Also records the supported Node versions in package.json, and corrects
the README, which said version 20 or newer when Vite needs 20.19.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PZUNgxTt93bKkqEiQ5P5ae
@ibrahimweng
ibrahimweng merged commit 30afcdb into main Aug 18, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants