Skip to content

Commit fd04c41

Browse files
committed
docs: plan transport pause and playhead
1 parent c685989 commit fd04c41

8 files changed

Lines changed: 127 additions & 13 deletions

PLANS.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ M1 should include:
2929

3030
Use this section as the current execution order for agent work. Feature document numbering describes the planned product sequence, but actual issue order may change as dependencies, review feedback, or implementation risks become clearer.
3131

32-
1. #3 Drum Step Sequencer -> `docs/features/04-drum-step-sequencer.md` (PR #15 in review)
33-
2. #2 Basic Piano Roll -> `docs/features/05-basic-piano-roll.md`
32+
1. #2 Basic Piano Roll -> `docs/features/05-basic-piano-roll.md`
33+
2. #16 Transport pause/resume and editor playhead -> `docs/features/07-transport-pause-and-playhead.md`
3434

3535
## Planned Milestones
3636

@@ -39,13 +39,14 @@ Use this section as the current execution order for agent work. Feature document
3939
3. Lookahead scheduler.
4040
4. Drum step sequencer.
4141
5. Basic piano roll.
42-
6. Hybrid clip loop playback.
43-
7. Sample import.
44-
8. Project export/import.
45-
9. IndexedDB autosave.
46-
10. Arrangement data model.
47-
11. Arrangement view.
48-
12. Mixer and basic effects.
42+
6. Transport pause/resume and editor playhead.
43+
7. Hybrid clip loop playback.
44+
8. Sample import.
45+
9. Project export/import.
46+
10. IndexedDB autosave.
47+
11. Arrangement data model.
48+
12. Arrangement view.
49+
13. Mixer and basic effects.
4950

5051
## Backlog
5152

docs/architecture.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The main rule is separation of concerns: UI rendering, persistence, and audio sc
1212

1313
- Render the transport, clip editor, drum sequencer, piano roll, and later arrangement views.
1414
- Dispatch user actions to state/model logic.
15-
- Display audio state such as playing/stopped and playhead position.
15+
- Display audio state such as stopped, playing, paused, and playhead position.
1616
- Use `requestAnimationFrame` for visual playheads where needed.
1717
- Avoid owning exact audio timing.
1818

docs/audio-engine.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ The documented default is PPQ 480. In 4/4, one bar is 1920 ticks and one 16-step
7272

7373
Transport state should include:
7474

75-
- Playing or stopped state.
75+
- Playback state: `stopped`, `playing`, or `paused`.
7676
- Tempo in BPM.
7777
- Current tick.
7878
- Audio start time.
@@ -82,6 +82,12 @@ Transport state should include:
8282

8383
Transport state may be mirrored into React for display, but React render timing must not drive exact audio playback.
8484

85+
Pause and stop have different meanings:
86+
87+
- Pause captures the current runtime playhead tick and stops future scheduling. Resume should continue from that tick.
88+
- Stop clears scheduling and resets the runtime playhead tick to the loop start, which is tick 0 for the M1 1-bar clip.
89+
- The paused playhead position is runtime state only. It should not be written to project JSON.
90+
8591
## Looping Behavior
8692

8793
For M1, loop playback targets a selected 1-bar clip. The default loop range is 0 to 1920 ticks.
@@ -96,6 +102,8 @@ When the user edits a drum pattern during playback, the UI may update the schedu
96102

97103
UI cursor and playhead animation may use `requestAnimationFrame` and read transport position from the audio engine. Visual playhead timing can be approximate. Exact sound timing must come from scheduled Web Audio events.
98104

105+
The UI may render a vertical playhead over the piano roll or drum sequencer by converting the current runtime tick into editor geometry. The playhead should wrap at the active loop boundary. It is display feedback only; moving or rendering the playhead must not be required for audio events to play on time.
106+
99107
## Future Extension Points
100108

101109
- Sampler instrument.

docs/features/04-drum-step-sequencer.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Feature: 04 Drum Step Sequencer
22

33
## Status
4-
In Review
4+
Done
55

66
## Goal
77

docs/features/06-main-daw-ui-shell.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Feature: 06 Main DAW UI Shell
22

33
## Status
4-
In Review
4+
Done
55

66
## Goal
77

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Feature: 07 Transport Pause and Playhead
2+
3+
## Status
4+
Planned
5+
6+
## Goal
7+
8+
Implement distinct pause, resume, and stop behavior for clip playback, and render a vertical runtime playhead in clip editors.
9+
10+
## Context
11+
12+
The current transport has only `playing` and `stopped` states. The play button can show a pause icon while playback is active, but pressing it stops playback in the same way as the stop button.
13+
14+
Before piano roll playback and hybrid clip loop playback become more complex, the app needs a clearer runtime transport model:
15+
16+
- Play from stopped starts at the beginning of the selected 1-bar clip.
17+
- Pause stops playback while preserving the current musical tick.
18+
- Resume continues from the paused tick.
19+
- Stop stops playback and resets the playhead to the beginning.
20+
21+
The visual playhead helps users understand where sequenced drum and note events are playing. It must not become the timing source for audio playback.
22+
23+
## Scope
24+
25+
Included:
26+
- Add a `paused` transport state.
27+
- Track the current runtime playhead position in ticks.
28+
- Capture the current tick when pausing.
29+
- Resume playback from the paused tick.
30+
- Stop playback and reset the runtime playhead to tick 0.
31+
- Render a vertical playhead in the piano roll editor.
32+
- Render a playhead in the drum step sequencer if practical for the same implementation pass.
33+
- Keep visual playhead animation driven by `requestAnimationFrame`.
34+
- Keep exact audio scheduling driven by `AudioContext.currentTime`.
35+
- Add focused tests for transport tick calculations, pause/resume offsets, and loop wrapping where practical.
36+
- Update relevant docs if the audio engine API or transport state model changes.
37+
38+
Excluded:
39+
- Arrangement timeline playhead.
40+
- Timeline scrubbing.
41+
- Realtime recording.
42+
- Automation.
43+
- Tempo automation.
44+
- Persisting runtime playhead position in project JSON.
45+
- Full transport keyboard shortcut support.
46+
47+
## Constraints
48+
49+
- Store musical position in ticks, not seconds.
50+
- Use PPQ 480, with the M1 1-bar loop spanning ticks 0 through 1920.
51+
- Treat the paused playhead position as runtime state, not serializable project data.
52+
- Do not store `AudioContext`, `AudioBuffer`, scheduler timers, source nodes, or playhead timers in project JSON.
53+
- React UI may display transport state and playhead position, but must not own exact audio timing.
54+
- The audio engine and scheduler must remain independent from React components.
55+
- The visual playhead may be approximate; audible event timing must remain scheduled against `AudioContext.currentTime`.
56+
- Use CSS Modules and semantic design tokens for playhead styling.
57+
- Inline styles are acceptable for computed playhead geometry, such as `transform`, `left`, or width derived from ticks.
58+
59+
## Done when
60+
61+
- Transport state can represent `stopped`, `playing`, and `paused`.
62+
- Pressing play from stopped starts playback from tick 0.
63+
- Pressing pause while playing stops scheduling and preserves the current playhead tick.
64+
- Pressing play from paused resumes playback from the paused tick.
65+
- Pressing stop from playing or paused stops playback and resets the playhead to tick 0.
66+
- The piano roll displays a vertical playhead aligned to the 1-bar grid.
67+
- The playhead wraps cleanly at the 1-bar loop boundary.
68+
- If included, the drum step sequencer displays a playhead or equivalent step-position indicator aligned to the 16-step grid.
69+
- Existing drum step playback behavior still works.
70+
- Tests cover pure transport/tick math where practical.
71+
72+
## Verification
73+
Run:
74+
- `npm run typecheck`
75+
- `npm run lint`
76+
- `npm run test`
77+
- `npm run build`
78+
79+
Manual check:
80+
- Start playback from stopped and confirm the playhead starts at the beginning.
81+
- Pause playback and confirm the playhead stops at its current position.
82+
- Resume playback and confirm it continues from the paused position.
83+
- Stop playback and confirm the playhead returns to the beginning.
84+
- Confirm the visual playhead loops across the 1-bar clip without jumping outside the editor grid.
85+
- Confirm drum steps still trigger at the expected musical positions after pause/resume.
86+
87+
## PR notes
88+
- Describe the transport state model and runtime tick fields added or changed.
89+
- Explain how pause differs from stop.
90+
- Explain how the visual playhead reads timing state without driving audio scheduling.
91+
- Note whether drum sequencer playhead display was included or deferred.

docs/testing.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ tests/unit/utils/tick-time.test.ts
4343

4444
- Tick-to-seconds conversion.
4545
- Loop boundaries.
46+
- Pause/resume tick offsets.
47+
- Playhead wrapping at loop boundaries.
4648
- Clip duplication.
4749
- Sample import.
4850
- Project export/import.
@@ -56,6 +58,7 @@ Manual audio checks should verify:
5658
- One-shot samples play repeatedly without reusing the same source node.
5759
- Loop playback does not double-trigger events at the loop boundary.
5860
- UI playhead movement roughly matches audible playback.
61+
- Pause preserves the runtime playhead position, resume continues from that position, and stop resets to the start.
5962
- Starting, stopping, and restarting transport leaves no stuck sounds.
6063
- Tempo changes behave as documented for the current milestone.
6164

docs/ui-design.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,17 @@ Inline styles are acceptable for computed editor geometry, including:
114114

115115
Keep static appearance in CSS Modules. Keep dynamic numeric layout derived from ticks, pitch, and grid dimensions.
116116

117+
## Playhead Display
118+
119+
Clip editors may render a vertical playhead to show the current runtime transport position.
120+
121+
- The playhead position should be derived from tick position and editor dimensions.
122+
- Use `requestAnimationFrame` for visual updates when playback is active.
123+
- Keep the playhead as visual feedback only; it must not drive exact audio scheduling.
124+
- Use CSS Modules and semantic design tokens for static playhead styling.
125+
- Inline styles are acceptable for computed playhead geometry such as `left` or `transform`.
126+
- When stopped, the playhead should reset to the start of the selected clip. When paused, it should remain at the paused tick.
127+
117128
## Sample Display Names
118129

119130
When displaying bundled drum sample names in the UI, derive the label from the `.wav` file name:

0 commit comments

Comments
 (0)