Skip to content

Commit c685989

Browse files
authored
Merge pull request #15 from boostcampwm-snu-2026-1/feat/3-drum-step-sequencer
feat: connect drum sequencer to clip model
2 parents bc3de0a + ca6f0a5 commit c685989

36 files changed

Lines changed: 1130 additions & 137 deletions

PLANS.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +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. #5 Lookahead Scheduler -> `docs/features/03-lookahead-scheduler.md` (PR #14 in review)
33-
2. #3 Drum Step Sequencer -> `docs/features/04-drum-step-sequencer.md`
34-
3. #2 Basic Piano Roll -> `docs/features/05-basic-piano-roll.md`
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`
3534

3635
## Planned Milestones
3736

docs/audio-engine.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ Events at the loop start should play when the loop begins. Events at the loop en
9090

9191
Loop stop clears the scheduler timer and prevents future windows from being scheduled. Events already submitted to Web Audio inside the current schedule-ahead window may still play briefly; keep `scheduleAheadTime` short enough that this limitation remains acceptable for interactive editing.
9292

93+
When the user edits a drum pattern during playback, the UI may update the scheduler's event list without restarting transport. Newly scheduled windows should use the latest serializable drum events. Events already submitted to Web Audio inside the current schedule-ahead window may still reflect the previous pattern because Web Audio scheduled source nodes cannot be unscheduled after `start(when)`.
94+
9395
## UI Playhead Separation
9496

9597
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.

docs/data-model.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,44 @@ Early clips may contain both drum events and note events. This keeps the M1 edit
2828

2929
Later, the model can evolve toward separate drum, MIDI, and audio clip types if arrangement and editing workflows need stronger separation.
3030

31+
## Bundled Drum Sample Naming and Display
32+
33+
Bundled drum sample files live under `public/samples/drums/`.
34+
35+
Use descriptive `.wav` file names with words separated by underscores, for example:
36+
37+
```text
38+
Fred_Kick_1.wav
39+
Fred_Closed_Hi-Hat.wav
40+
```
41+
42+
The app derives sample metadata from the file name:
43+
44+
- Sample IDs are the file stem lowercased with underscores replaced by hyphens.
45+
- Display names remove `.wav`, replace underscores with spaces, and uppercase the result.
46+
47+
Examples:
48+
49+
- `Fred_Kick_1.wav` -> sample ID `fred-kick-1`, display name `FRED KICK 1`.
50+
- `Fred_Closed_Hi-Hat.wav` -> sample ID `fred-closed-hi-hat`, display name `FRED CLOSED HI-HAT`.
51+
52+
## Initial Drum Clip Implementation
53+
54+
The initial drum step sequencer stores lane settings and drum hits in the selected hybrid clip. A 16-step grid maps step indices to ticks with `stepIndex * 120`.
55+
56+
The clip stores `drumLanes` as an ordered array. That array controls both visual lane order and the current sample assigned to each lane. Reordering lanes or changing a lane's sample must update serializable clip state, not runtime-only audio state.
57+
58+
Initial drum lanes map to bundled sample IDs:
59+
60+
- `kick` -> `fred-kick-1`
61+
- `snare` -> `fred-snare-1`
62+
- `closedHat` -> `fred-closed-hi-hat`
63+
- `openHat` -> `fred-open-hi-hat`
64+
65+
Drum event IDs are deterministic within a clip using the clip ID, lane ID, and start tick. Runtime playback converts these serializable events into audio engine sample loop events; the project model itself does not store `AudioBuffer` or other Web Audio objects.
66+
67+
When a lane sample changes, existing `DrumEvent` objects for that lane should be updated to the new `sampleId` so playback and project export reflect the visible lane setting.
68+
3169
## Illustrative Types
3270

3371
These snippets show model intent. Implementation may refine names and fields, but changes to model semantics must update this document.
@@ -61,10 +99,17 @@ export interface Clip {
6199
id: string;
62100
name: string;
63101
lengthTicks: Tick;
102+
drumLanes: DrumLaneDefinition[];
64103
drumEvents: DrumEvent[];
65104
noteEvents: NoteEvent[];
66105
}
67106

107+
export interface DrumLaneDefinition {
108+
id: "kick" | "snare" | "closedHat" | "openHat";
109+
label: string;
110+
sampleId: string;
111+
}
112+
68113
export interface ClipInstance {
69114
id: string;
70115
clipId: string;

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

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

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

66
## Goal
77

@@ -18,6 +18,9 @@ Included:
1818
- Add initial lanes for kick, snare, closed hi-hat, and open hi-hat.
1919
- Toggle steps on and off.
2020
- Store events in the clip model using tick positions.
21+
- Store lane sample assignment and lane order in the clip model.
22+
- Allow lane sample selection from bundled drum samples.
23+
- Allow vertical lane reordering.
2124
- Use CSS Modules for styling.
2225
- Use semantic buttons for step toggles.
2326
- Integrate with the existing audio playback/scheduler if already present.
@@ -38,6 +41,7 @@ Excluded:
3841
## Done when
3942
- Users can toggle drum steps for the four initial lanes.
4043
- Drum events are added to and removed from the selected clip model.
44+
- Lane sample selection and lane order update the selected clip model.
4145
- Step buttons have accessible names and visible focus states.
4246
- Playback integration works if the scheduler exists.
4347

docs/ui-design.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,22 @@ 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+
## Sample Display Names
118+
119+
When displaying bundled drum sample names in the UI, derive the label from the `.wav` file name:
120+
121+
- Remove the `.wav` extension.
122+
- Replace underscores (`_`) with spaces.
123+
- Convert the result to uppercase.
124+
125+
Example: `Fred_Kick_1.wav` displays as `FRED KICK 1`.
126+
127+
## Drum Lane Editing
128+
129+
Drum lane names can act as sample selectors. Clicking a lane name may open a compact scrollable list of bundled drum samples. Render this menu as a popover above clipping editor containers when needed so it is not cut off by panel or workspace overflow. Selecting a sample should update the lane's visible label, the lane's `sampleId`, and existing drum events for that lane in serializable clip state.
130+
131+
Drum lanes may be reordered vertically with drag and drop. The visual order should come from the selected clip's ordered `drumLanes` array rather than a hard-coded component order.
132+
117133
## UI Reference Policy
118134

119135
If a design prototype uses Tailwind, inline styles, or CDN assets, treat it as visual reference only. Convert the design into semantic React components, CSS Modules, and shared CSS variables.
161 KB
Binary file not shown.
161 KB
Binary file not shown.
161 KB
Binary file not shown.
82.5 KB
Binary file not shown.
181 KB
Binary file not shown.

0 commit comments

Comments
 (0)