Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions docs/plans/roadmap-themed-sprints-2026-03.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Research Backlog Themed Sprint Roadmap (#942-#975)

## Scope

- Sources:
- `origin/claude/research-daw-synths-KU2At:.llm/research/*`
- GitHub issues `#942-#975`
- current `main` code synced on 2026-03-27
- Goal:
- convert the research backlog into theme-based sprints
- sequence work around shared engine and store dependencies
- keep implementation reviewable through small, testable PRs

## Planning Principles

- Ship data model and engine primitives before surface-level UI.
- Preserve dual-surface parity: every sprint must add or extend `window.__store` actions in addition to visual controls.
- Prefer PR slices that touch one interaction family at a time and land with browser-testable workflows.
- Keep dark-theme quality, keyboard access, and agent automation coverage in every sprint, not only at the end.
- Treat issues `#970`, `#974`, and `#975` as trust multipliers: they improve first-run confidence and should progress in parallel with core audio work.

## Dependency Summary

| Sprint | Theme | Issues | Depends On | Planned PRs |
|---|---|---|---|---|
| 01 | Synth Foundation | `#942 #943 #944 #945 #946 #953 #964` | none | 4 |
| 02 | Sampling, Drum Rack, and Render Pipeline | `#948 #949 #950 #951 #952 #958 #961` | 01 | 4 |
| 03 | Mixer, Device Graph, and Routing | `#957 #959 #965 #969` | 01 | 4 |
| 04 | MIDI, Rhythm, and Automation Editors | `#967 #968 #973` | 01, 03 | 3 |
| 05 | Arrangement and Recording Workflows | `#966 #972` | 02, 04 | 3 |
| 06 | Onboarding, Library, and Accessibility | `#970 #971 #975` | none | 3 |
| 07 | Collaboration, Cloud, and Project Lifecycle | `#974` | 06 | 4 |
| 08 | Advanced Sound Design Lab | `#947 #954 #955 #956 #960 #962 #963` | 01, 02, 03 | 4 |

## Execution Lanes

### Lane A — Audio Platform

- Sprint 01
- Sprint 02
- Sprint 03
- Sprint 08

### Lane B — Editing Workflows

- Sprint 04
- Sprint 05

### Lane C — Experience and Trust

- Sprint 06
- Sprint 07

## Recommended Order

1. Land Sprint 01 first to replace preset-only instrument assumptions with a real instrument state model.
2. Start Sprint 06 in parallel once Sprint 01 is underway, because onboarding/accessibility mostly avoids audio-engine conflict.
3. Run Sprint 02 and Sprint 03 after Sprint 01 because both need richer instrument and effect schemas.
4. Start Sprint 04 once Sprint 03 has automation-arm and device parameter hooks available.
5. Start Sprint 05 after Sprint 02 and Sprint 04 so recording, comping, and clip operations share the new render and editor primitives.
6. Start Sprint 07 after Sprint 06 so first-run and project-library UX do not diverge from cloud and share-player flows.
7. Keep Sprint 08 last because it depends on the synth, sampler, routing, and modulation foundations from Sprints 01-03.

## Branch and PR Conventions

- Sprint branches:
- `feat/v0.0.x-sprint-01-synth-foundation`
- `feat/v0.0.x-sprint-02-sampling-drum-render`
- `feat/v0.0.x-sprint-03-mixer-device-routing`
- `feat/v0.0.x-sprint-04-midi-rhythm-automation`
- `feat/v0.0.x-sprint-05-arrangement-recording`
- `feat/v0.0.x-sprint-06-onboarding-library-accessibility`
- `feat/v0.0.x-sprint-07-collaboration-cloud`
- `feat/v0.0.x-sprint-08-advanced-sound-design`
- PR naming:
- `feat: sprint 01 PR1 instrument state model`
- `feat: sprint 03 PR2 device chain UX`
- `feat: sprint 06 PR1 accessible control primitives`

## Done Criteria For Every Sprint

- `npx tsc --noEmit`
- `npm run build`
- targeted Vitest coverage for the new engine/store surface
- at least one browser workflow covering human interaction and one `window.__store` workflow covering agent interaction
- no new console noise outside explicit error handlers
- updated docs/plans for any scope change discovered during implementation

## Sprint Documents

- [Sprint 01 — Synth Foundation](./sprint-01-synth-foundation.md)
- [Sprint 02 — Sampling, Drum Rack, and Render Pipeline](./sprint-02-sampling-drum-render.md)
- [Sprint 03 — Mixer, Device Graph, and Routing](./sprint-03-mixer-device-routing.md)
- [Sprint 04 — MIDI, Rhythm, and Automation Editors](./sprint-04-midi-rhythm-automation.md)
- [Sprint 05 — Arrangement and Recording Workflows](./sprint-05-arrangement-recording.md)
- [Sprint 06 — Onboarding, Library, and Accessibility](./sprint-06-onboarding-library-accessibility.md)
- [Sprint 07 — Collaboration, Cloud, and Project Lifecycle](./sprint-07-collaboration-cloud.md)
- [Sprint 08 — Advanced Sound Design Lab](./sprint-08-advanced-sound-design.md)
86 changes: 86 additions & 0 deletions docs/plans/sprint-01-synth-foundation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Sprint 01 — Synth Foundation

## User Stories

- As a producer, I want every instrument track to expose editable synth parameters, so that I can shape sounds instead of swapping only preset names.
- As a producer, I want subtractive and FM synth building blocks to behave like real DAW instruments, so that ACE-Step can cover bread-and-butter bass, lead, pad, and keys workflows.
- As an AI agent, I want synth state to be represented in the project store instead of hidden inside Tone instances, so that I can automate instrument design through `window.__store`.

## Problem

- Issues `#942 #943 #944 #945 #946 #953 #964` all describe expected baseline synth behavior, but the current app still treats instruments as a preset string plus a fixed Tone setup.
- The backlog mixes UI asks with engine asks, yet the real blocker is missing instrument state and routing primitives.

## Root Cause

- `src/types/project.ts:7-13` models instruments as `TrackType` plus a `SynthPreset` string, which cannot represent oscillator, filter, modulation, or engine-specific state.
- `src/engine/SynthEngine.ts:10-52` hardcodes six preset branches on `Tone.PolySynth(Tone.Synth)` and never persists parameter snapshots.
- `src/engine/SynthEngine.ts:66-139` caches one synth per track keyed only by preset, so changing a single parameter would currently require replacing the whole instance.
- `src/components/pianoroll/PianoRoll.tsx:122-155` and `src/components/pianoroll/PianoRoll.tsx:224-260` expose sampler config and editor toolbar state, but there is no synth editor surface or store-backed synth parameter UI.

## Solution

### Deliverables

- Introduce a track-level `instrument` model that separates engine kind from preset label.
- Add a subtractive synth schema with oscillator, amp envelope, filter, filter envelope, LFO, and unison settings.
- Add an FM synth schema with at least carrier/modulator ratio, level, waveform, and modulation index.
- Build a synth editor panel with visual envelope sections and collapsible advanced controls.
- Add preset snapshots backed by factory JSON plus IndexedDB user presets.

### Issue Map

- `#942` synth parameter editing baseline
- `#943` filter envelope
- `#944` routeable LFO
- `#945` unison/detune
- `#946` FM instrument
- `#953` preset browser/save/load
- `#964` visual synth editor

### Proposed PR Slices

1. `feat: add track instrument state model and migration`
- extend `src/types/project.ts`
- add store migration/helpers in `src/store/projectStore.ts`
- expose agent-safe actions in `src/main.tsx`
2. `feat: add subtractive synth parameter engine and editor essentials`
- update `src/engine/SynthEngine.ts`
- add synth editor component under `src/components/pianoroll/`
- support `#942` and `#943`
3. `feat: add LFO, unison, and FM engine support`
- implement `#944 #945 #946`
- add visual status/routing previews
4. `feat: add preset browser and user preset persistence`
- implement `#953 #964`
- ship factory preset JSON and IndexedDB user presets

## Verification

- `npx tsc --noEmit`
- `npm run build`
- `npx vitest run src/engine/__tests__/SynthEngine.test.ts src/store/__tests__/projectStore.test.ts`
- add E2E coverage:
- create a piano-roll track
- change oscillator, filter, envelope, and preset in UI
- verify the same state through `window.__store.getState().project`
- manual workflow:
- create Bass patch
- duplicate track
- switch duplicate to FM Bell
- save and reload project
- confirm both instruments restore correctly

## Files To Touch

- `docs/plans/sprint-01-synth-foundation.md`
- `src/types/project.ts`
- `src/store/projectStore.ts`
- `src/engine/SynthEngine.ts`
- `src/components/pianoroll/PianoRoll.tsx`
- `src/components/pianoroll/`
- `src/main.tsx`
- `src/services/` preset persistence helpers
- `tests/e2e/`
- `src/engine/__tests__/`
- `src/store/__tests__/`
80 changes: 80 additions & 0 deletions docs/plans/sprint-02-sampling-drum-render.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Sprint 02 — Sampling, Drum Rack, and Render Pipeline

## User Stories

- As a producer, I want sampler instruments to use realistic zones, slices, and warp behavior, so that browser-based playback does not feel like a toy pitch shifter.
- As a beat-maker, I want the drum machine to accept my own samples and pad-level shaping, so that I can build real kits instead of only choosing four synthesized kits.
- As a producer and AI agent, I want freeze and bounce workflows to reduce CPU while preserving reversibility, so that large projects stay stable.

## Problem

- Issues `#948 #949 #950 #951 #952 #958 #961` all sit on the same missing platform: the app has one-sample playback, synthesized drum pads, and partial bounce primitives, but not a general sample-instrument architecture.

## Root Cause

- `src/types/project.ts:57-81` only supports a single `SamplerConfig` buffer with trim and ADSR, and `src/types/project.ts:96-108` only gives each drum pad `sampleKey`, `volume`, and `pan`.
- `src/engine/SamplerEngine.ts:81-220` manages one `AudioBuffer` per track and derives pitch purely from `playbackRate`, which blocks multi-zone, velocity-layer, slice, and pitch-independent stretch workflows.
- `src/engine/DrumEngine.ts:46-220` constructs every drum sound from fixed Tone synth factories instead of per-pad instrument descriptors and effect chains.
- `src/store/projectStore.ts:2292-2385` exposes `freezeTrack`, `unfreezeTrack`, `flattenTrack`, and `bounceInPlace`, but the state model and UX stop short of a complete freeze/unfreeze workflow.
- `src/components/sequencer/DrumMachineEditor.tsx:170-260` only exposes kit selection and per-pad volume details, not sample loading, tuning, or pad processing.

## Solution

### Deliverables

- Replace the single-buffer sampler model with zone-based sampler definitions.
- Add velocity layers, round-robin, and slice maps that remain scriptable through the store.
- Add per-pad sample mode, tune, envelope, filter, drive, and send state to the drum machine.
- Add pitch-independent time stretch and warp markers for sampler clips and slices.
- Complete track freeze/unfreeze/bounce UX on top of the existing offline render hooks.

### Issue Map

- `#948` multi-sample zones
- `#949` user sample loading on pads
- `#950` per-pad effects and tuning
- `#951` velocity layers and crossfading
- `#952` audio slice mode
- `#958` warp/time-stretch
- `#961` freeze/bounce track to audio

### Proposed PR Slices

1. `feat: add sampler zone model and engine migration`
- zone schema, velocity ranges, round-robin
2. `feat: add drum pad sample mode and per-pad shaping`
- sample loading, choke groups, pad filter/drive/send
3. `feat: add slice mode and warp-ready sample UI`
- transient slicing, manual slices, warp marker model
4. `feat: add freeze-unfreeze workflow and render progress`
- full `#961` UX, store actions, browser tests

## Verification

- `npx tsc --noEmit`
- `npm run build`
- `npx vitest run src/services/__tests__/bounceInPlace.test.ts src/store/__tests__/drumMachine.test.ts`
- add new unit coverage:
- sampler zone selection by pitch and velocity
- slice-to-MIDI mapping
- freeze/unfreeze persistence
- browser workflows:
- drag a sample onto a drum pad, trigger it, reload project
- load a sample into sampler, create slices, trigger them from piano roll
- freeze a synth track, confirm CPU-saving audio playback, unfreeze it

## Files To Touch

- `docs/plans/sprint-02-sampling-drum-render.md`
- `src/types/project.ts`
- `src/store/projectStore.ts`
- `src/engine/SamplerEngine.ts`
- `src/engine/DrumEngine.ts`
- `src/components/pianoroll/QuickSamplerEditor.tsx`
- `src/components/sequencer/DrumMachineEditor.tsx`
- `src/components/pianoroll/`
- `src/hooks/useTransport.ts`
- `src/services/bounceInPlace.ts`
- `src/services/audioFileManager.ts`
- `tests/e2e/`
- `src/store/__tests__/`
75 changes: 75 additions & 0 deletions docs/plans/sprint-03-mixer-device-routing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Sprint 03 — Mixer, Device Graph, and Routing

## User Stories

- As a mixer, I want channel strips and device chains to expose real routing, metering, and insert behavior, so that I can mix inside ACE-Step without treating the mixer as a placeholder.
- As a producer, I want routing-heavy effects such as convolution reverb and sidechain ducking, so that modern mix workflows are possible.
- As an AI agent, I want device parameters and routing choices to exist in store state, so that automated mix flows can modify them safely.

## Problem

- Issues `#957 #959 #965 #969` look separate, but they are all symptoms of one limitation: there is no unified device graph between the effect model, mixer surface, and audio routing layer.

## Root Cause

- `src/components/mixer/MixerPanel.tsx:12-18` caps inserts and sends at four and two, and `src/components/mixer/MixerPanel.tsx:144-247` renders fixed sections without I/O routing, dB markings, or advanced metering.
- `src/components/mixer/EffectChain.tsx:51-141` encodes effect presets inline and `src/components/mixer/EffectChain.tsx:171-279` renders a basic device card row without rack nesting, A/B states, preset library, or searchable add flow.
- `src/engine/EffectsEngine.ts:97-227` builds linear Tone node chains, ships only algorithmic reverb, and has no first-class effect-rack or sidechain input abstraction.
- `src/engine/EffectsEngine.ts:233-247` rebuilds a single linear chain per track, which is insufficient for parallel racks, convolution branches, and visual routing feedback.

## Solution

### Deliverables

- Introduce a track device graph abstraction that supports serial and parallel chains.
- Upgrade channel strips with RMS plus peak metering, dB scale, insert management, pre/post sends, solo-safe, and simple I/O routing.
- Rebuild the device chain UX with searchable add, collapse, reorder, preset persistence, and rack containers.
- Add convolution reverb and sidechain routing as first-class graph nodes.

### Issue Map

- `#957` convolution reverb
- `#959` sidechain routing UI
- `#965` pro-grade mixer panel
- `#969` device-view redesign

### Proposed PR Slices

1. `feat: add mixer meter upgrade and channel-strip state`
- RMS/peak meters, dB scale, insert slot expansion
2. `feat: add searchable device chain UX and drag reorder`
- searchable add menu, collapse, preset surface
3. `feat: add convolution reverb and visual processor feedback`
- IR loading, EQ curve, gain reduction meter
4. `feat: add sidechain routing and send-state upgrades`
- sidechain source selector, pre/post send toggle, solo-safe

## Verification

- `npx tsc --noEmit`
- `npm run build`
- `npx vitest run src/engine/__tests__/effectsEngineNativeNode.test.ts src/store/__tests__/sendsReturns.test.ts tests/unit/StatusBar.test.tsx`
- add new unit coverage:
- device graph serialization
- sidechain routing selection
- convolution preset persistence
- browser workflows:
- create a reverb rack and reorder devices
- set kick as sidechain source for bass compressor
- verify insert count, send toggles, and meter behavior in mixer

## Files To Touch

- `docs/plans/sprint-03-mixer-device-routing.md`
- `src/types/project.ts`
- `src/store/projectStore.ts`
- `src/engine/EffectsEngine.ts`
- `src/components/mixer/MixerPanel.tsx`
- `src/components/mixer/EffectChain.tsx`
- `src/components/mixer/EffectCards.tsx`
- `src/components/mixer/LevelMeter.tsx`
- `src/components/ui/Knob.tsx`
- `src/components/mixer/VerticalFader.tsx`
- `src/engine/__tests__/`
- `src/store/__tests__/`
- `tests/e2e/`
Loading
Loading