Skip to content

Commit 9b6e702

Browse files
committed
Add MIDI channel management and CC lane features
- Introduced MIDI channel selection in ChannelStrip, allowing users to set output channels (1-16) for MIDI clips. - Implemented linked MIDI channel clips functionality in EditManager, enabling the creation of multiple linked MIDI clips with display names. - Enhanced NoteGrid to support multiple MIDI clips, allowing for better management of notes across different channels. - Added CC lane editor in PianoRoll, providing users with the ability to draw and edit CC events alongside note editing. - Updated CMakeLists.txt to include new source files related to MIDI channel and CC lane features.
1 parent 8a8522e commit 9b6e702

26 files changed

Lines changed: 2261 additions & 292 deletions

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ set(FREEDAW_SOURCES
9797
src/ui/pianoroll/NoteGrid.h src/ui/pianoroll/NoteGrid.cpp
9898
src/ui/pianoroll/NoteItem.h src/ui/pianoroll/NoteItem.cpp
9999
src/ui/pianoroll/VelocityLane.h src/ui/pianoroll/VelocityLane.cpp
100+
src/ui/pianoroll/CcLane.h src/ui/pianoroll/CcLane.cpp
101+
src/ui/pianoroll/ChannelColors.h
100102
src/ui/pianoroll/PianoRollRuler.h src/ui/pianoroll/PianoRollRuler.cpp
101103
src/ui/routing/RoutingView.h src/ui/routing/RoutingView.cpp
102104
src/ui/routing/RoutingNode.h src/ui/routing/RoutingNode.cpp

IMPLEMENTATION_GUIDE.md

Lines changed: 74 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -162,92 +162,86 @@
162162

163163
## 3. Automation Envelopes
164164

165-
### 3.1 Automation lane UI on timeline **[MUST]**
165+
### 3.1 ~~Automation lane UI on timeline~~ **[MUST]** -- DONE
166166

167-
**What:** Add expandable automation lanes below each track in the timeline, showing parameter envelopes that can be edited with point add/move/delete.
167+
**What:** Expandable automation lanes below each track in the timeline, showing parameter envelopes that can be edited with point add/move/delete, freehand draw, and curve shape editing.
168168

169-
**Where to start:**
170-
- `src/ui/timeline/TimelineView.cpp` -- tracks are laid out vertically at `y = trackIndex * trackHeight_`. Automation lanes go below each track's clip area.
171-
- `src/ui/timeline/TrackHeaderWidget.cpp` -- add an "Automation" toggle or dropdown to select which parameter to show.
172-
- Coordinate system: `pixelsPerBeat_` for X, extend Y for the automation lane height.
173-
174-
**New files:**
175-
- `src/ui/timeline/AutomationLaneItem.h` / `.cpp` -- `QGraphicsItem` subclass that draws the envelope line and handles point interaction.
176-
- `src/ui/timeline/AutomationPoint.h` / `.cpp` -- (optional, can be inline) represents a draggable point.
169+
**Files created:**
170+
- `src/ui/timeline/AutomationLaneItem.h/.cpp` -- `QGraphicsItem` that draws the envelope curve (sampled from engine for pixel-perfect accuracy), handles point creation, freehand drawing, and curve segment bending.
171+
- `src/ui/timeline/AutomationPointItem.h/.cpp` -- Draggable diamond-shaped point handles with snap, shift-constrain, value tooltips, and right-click curve shape presets.
172+
- `src/ui/timeline/AutomationLaneHeader.h/.cpp` -- Header widget with parameter dropdown (Volume, Pan, all plugin params), bypass toggle, and close button.
173+
- `src/ui/timeline/EnvelopeUtils.h` -- Shared coordinate/path/hit-test utilities designed for reuse by future CC lane.
177174

178-
**Tracktion Engine API:**
179-
- Each `te::Plugin` has `getAutomatableParameters()` returning `juce::Array<te::AutomatableParameter*>`.
180-
- Each `te::AutomatableParameter` has a `getCurve()` method returning `te::AutomationCurve&`.
181-
- `te::AutomationCurve` has: `getNumPoints()`, `getPointTime(i)`, `getPointValue(i)`, `addPoint(time, value, curveValue)`, `removePoint(index)`, `movePoint(index, newTime, newValue, ...)`.
182-
- Volume and pan are on `te::VolumeAndPanPlugin` (present on every track): `volParam` and `panParam`.
183-
- Automation persists in the `.tracktionedit` XML automatically.
184-
185-
**Implementation:**
186-
1. Add a parameter selector per track (dropdown in `TrackHeaderWidget` listing "Volume", "Pan", and plugin parameter names).
187-
2. When a parameter is selected, create an `AutomationLaneItem` in the `QGraphicsScene` positioned below the track's clip row.
188-
3. `AutomationLaneItem::paint()` reads points from `te::AutomationCurve` and draws lines/curves.
189-
4. Mouse interaction:
190-
- Double-click empty space: add point via `curve.addPoint(...)`.
191-
- Drag existing point: `curve.movePoint(...)`.
192-
- Right-click point: delete via `curve.removePoint(...)`.
193-
5. Adjust `TimelineView` layout to account for open automation lanes (increase effective track height when lane is visible).
194-
6. Sync with playback: during transport play, the engine reads the curve automatically; no extra wiring needed.
175+
**Files modified:**
176+
- `TimelineView.h/.cpp` -- Variable-height `TrackLayoutInfo` layout system, automation lane management, resize handles, playhead-driven lane updates.
177+
- `TrackHeaderWidget.h/.cpp` -- "Auto" disclosure button, `setAutomationVisible()` for state sync.
178+
- `EditManager.h/.cpp` -- `getAutomatableParamsForTrack()`, `getVolumeParam()`, `getPanParam()` helpers.
179+
- `CMakeLists.txt` -- Added 7 new source files.
195180

196-
**Acceptance criteria:**
197-
- User can show/hide an automation lane per track.
198-
- User can add, move, and delete automation points for volume, pan, and plugin parameters.
199-
- Automation plays back correctly and exports correctly.
200-
- Points persist after save/reload.
181+
**Features implemented:**
182+
- Single automation lane per track with parameter switcher dropdown.
183+
- Double-click to add points; drag to move with grid snap and shift-constrain.
184+
- Freehand draw mode with automatic simplification.
185+
- Ctrl+drag curve segments to bend (ease in/out); right-click presets (Linear, Ease In/Out, Sharp, Step).
186+
- Discrete/boolean parameter support (step rendering, state snapping).
187+
- Resizable lane height (50-120px) via drag handle.
188+
- Curve line with drop shadow; playback position dot that follows the curve.
189+
- Value labels on lane edges (dB for volume, L/R for pan, % for generic).
190+
- Keyboard shortcut: `A` to toggle automation lane on selected track.
191+
- Automation data persists in `.tracktionedit` files automatically.
201192

202193
---
203194

204-
### 3.2 Automation read/write modes on mixer **[SHOULD]**
205-
206-
**What:** Add Read/Write/Off buttons to each channel strip so automation can be recorded by moving faders during playback.
195+
### 3.2 ~~Automation read/write/touch/latch modes on mixer~~ **[SHOULD]** -- DONE
207196

208-
**Where to start:** `src/ui/mixer/ChannelStrip.cpp` -- add buttons near the existing mute/solo row.
197+
**What:** Per-track automation mode button on each channel strip (including master) with four modes: Read, Touch, Latch, Write.
209198

210-
**Tracktion Engine API:**
211-
- `te::AutomatableParameter::setAutomationMode(...)` with modes like `readEnabled`, `writeEnabled`.
212-
- When write is enabled and transport is playing, moving a parameter value writes to the automation curve.
199+
**Implementation:**
200+
- `ChannelStrip.cpp` -- Cycle button (READ → TOUCH → LATCH → WRITE → READ) sets per-track `track->automationMode` and global `AutomationRecordManager` flags.
201+
- Touch mode: records only while actively moving a control, reverts to reading on release.
202+
- Latch mode: starts recording on first touch, holds last value until stop.
203+
- Write mode: records all params from playback start (most destructive).
204+
- Master channel strip automation supported via `edit->getMasterTrack()->automationMode`.
205+
- Volume faders, pan knobs, and effect parameter knobs visually follow automation during playback (30fps polling).
206+
- Scrubbing (moving playhead while stopped) updates controls to show automation value at that position.
207+
- Controls only tracked in non-WRITE modes to avoid fighting with user input.
208+
- Pan automation recording fixed: uses `panParam->setParameter()` instead of `pan.setValue()`.
213209

214210
---
215211

216212
## 4. MIDI CC Lanes and Channel Handling
217213

218-
### 4.1 CC lane editor in piano roll **[MUST]**
219-
220-
**What:** Add a CC lane panel below the velocity lane in the piano roll, allowing users to draw and edit CC events.
214+
### 4.1 ~~CC lane editor in piano roll~~ **[MUST]** -- DONE
221215

222-
**Where to start:**
223-
- `src/ui/pianoroll/PianoRollEditor.cpp` -- the `VelocityLane` is positioned below `NoteGrid` (line ~136). The CC lane goes in the same layout, below velocity.
224-
- `src/ui/pianoroll/VelocityLane.cpp` -- use as a structural template for the CC lane widget.
216+
**What:** Automation-grade CC lane panel below the velocity lane in the piano roll, with full point editing.
225217

226-
**New files:**
227-
- `src/ui/pianoroll/CcLane.h` / `.cpp` -- `QWidget` subclass for drawing/editing CC events.
218+
**Files created:**
219+
- `src/ui/pianoroll/CcLane.h/.cpp` -- QWidget with cached point model, diamond-handle painting, step-curve rendering via `EnvelopeUtils`, freehand draw, individual and bulk point editing.
228220

229-
**Tracktion Engine API:**
230-
- `te::MidiClip``getSequence()` returns `te::MidiList&`.
231-
- `te::MidiList` has `getControllerEvents()` returning controller event data.
232-
- To add a CC event: `midiList.addControllerEvent(beatPosition, ccNumber, ccValue, undoManager)`.
233-
- To remove: iterate events and remove by index.
234-
- CC numbers: 1 (Mod Wheel), 7 (Volume), 10 (Pan), 11 (Expression), 64 (Sustain).
235-
236-
**Implementation:**
237-
1. Add a CC number selector (combo box) in `PianoRollEditor` toolbar: CC1, CC7, CC10, CC11, CC64, plus "Other..." for arbitrary CC.
238-
2. `CcLane` widget:
239-
- X axis: beats (synced with `NoteGrid` scroll and zoom via `pixelsPerBeat`).
240-
- Y axis: CC value 0-127.
241-
- Draw mode: click-drag to draw CC values (similar to velocity lane drag).
242-
- Edit mode: click existing events to select and move.
243-
3. Connect to undo: pass `edit->getUndoManager()` to all add/remove calls.
244-
4. On clip change or edit, emit `midiClipModified` so the lane refreshes.
221+
**Files modified:**
222+
- `PianoRollEditor.h/.cpp` -- CC number combo box (CC1/7/10/11/64 + arbitrary via "Other..."), CC row layout below velocity, scroll/zoom/clip sync, snap function pass-through.
223+
- `CMakeLists.txt` -- Added CcLane source files.
245224

246-
**Acceptance criteria:**
247-
- User can select a CC number and see existing CC data drawn as a lane.
248-
- User can draw new CC values by clicking/dragging.
249-
- CC data plays back through the MIDI output.
250-
- CC data persists after save/reload.
225+
**Features implemented:**
226+
- CC number selector combo box in toolbar with preset CCs and custom entry.
227+
- Step-curve rendering with translucent fill using `EnvelopeUtils::buildEnvelopePath(discrete=true)`.
228+
- Diamond point handles at each CC event (8px normal, 10px hovered), styled like `AutomationPointItem`.
229+
- Double-click to add a point at any position.
230+
- Click-drag on empty space for freehand CC drawing with range-overwrite and interval simplification.
231+
- Alt+drag (or Line tool) for straight-line CC drawing -- linear ramp between start and end points.
232+
- Freehand/Line draw tool toggle buttons in the CC header panel for users who prefer clicking over modifier keys.
233+
- Point drag with grid snap and shift-constrain (horizontal or vertical lock).
234+
- Value tooltip during drag (e.g. "CC1: 87").
235+
- Ctrl+drag rubber-band multi-select; Shift+click for additive selection toggle.
236+
- Bulk move: drag any selected point to move entire selection as a group.
237+
- Delete key removes selected points; right-click context menu for single/multi delete and "Add Point Here".
238+
- Ctrl+A selects all; Escape clears selection.
239+
- Horizontal reference lines at 25%/50%/75% with value labels.
240+
- Collapsible CC lane (collapsed by default) with disclosure arrow; "Vel" label on velocity lane header.
241+
- Selected CC name displayed in the left header panel alongside the collapse toggle and draw tool buttons.
242+
- Horizontal separator between velocity lane and CC lane.
243+
- Undo/redo for all operations via `edit->getUndoManager()`.
244+
- CC data persists in `.tracktionedit` files automatically (Tracktion ValueTree serialization).
251245

252246
---
253247

@@ -817,14 +811,15 @@
817811

818812
## 17. Summary: New Files to Create
819813

820-
| File | Purpose |
821-
|------|---------|
822-
| `src/ui/dialogs/AudioSettingsDialog.h/.cpp` | Audio device selection dialog |
823-
| `src/ui/dialogs/RecoveryDialog.h/.cpp` | Crash recovery prompt on startup |
824-
| `src/ui/timeline/AutomationLaneItem.h/.cpp` | Automation envelope drawing and editing in timeline |
825-
| `src/ui/pianoroll/CcLane.h/.cpp` | CC event drawing and editing lane in piano roll |
826-
827-
All other tasks modify existing files only.
814+
| File | Purpose | Status |
815+
|------|---------|--------|
816+
| `src/ui/dialogs/AudioSettingsDialog.h/.cpp` | Audio device selection dialog | DONE |
817+
| `src/ui/dialogs/RecoveryDialog.h/.cpp` | Crash recovery prompt on startup | DONE |
818+
| `src/ui/timeline/AutomationLaneItem.h/.cpp` | Automation envelope drawing and editing in timeline | DONE |
819+
| `src/ui/timeline/AutomationPointItem.h/.cpp` | Draggable automation point handles | DONE |
820+
| `src/ui/timeline/AutomationLaneHeader.h/.cpp` | Automation lane header with parameter selector | DONE |
821+
| `src/ui/timeline/EnvelopeUtils.h` | Shared coordinate/path utilities for automation and CC lanes | DONE |
822+
| `src/ui/pianoroll/CcLane.h/.cpp` | CC event drawing and editing lane in piano roll | DONE |
828823

829824
All other tasks modify existing files. Remember to add new `.h`/`.cpp` pairs to `FREEDAW_SOURCES` in `CMakeLists.txt`.
830825

@@ -841,8 +836,8 @@ Quick-reference of every task sorted by priority.
841836
| ~~1.3~~ | ~~Crash recovery on startup~~ | ~~Data Safety~~ DONE |
842837
| ~~2.1~~ | ~~Audio settings dialog~~ | ~~Device/Performance~~ DONE |
843838
| ~~2.2~~ | ~~Live status bar~~ | ~~Device/Performance~~ DONE |
844-
| 3.1 | Automation lane UI on timeline | Automation |
845-
| 4.1 | CC lane editor in piano roll | MIDI |
839+
| ~~3.1~~ | ~~Automation lane UI on timeline~~ | ~~Automation~~ DONE |
840+
| ~~4.1~~ | ~~CC lane editor in piano roll~~ | ~~MIDI~~ DONE |
846841
| 4.2 | MIDI channel selection | MIDI |
847842
| 5.1 | Loop in/out region UI | Transport |
848843
| 5.2 | Metronome / click track | Transport |
@@ -857,7 +852,7 @@ Quick-reference of every task sorted by priority.
857852
|----|------|---------|
858853
| ~~1.4~~ | ~~Window title with project name~~ | ~~Data Safety~~ DONE |
859854
| 1.5 | Recent projects list | Data Safety |
860-
| 3.2 | Automation read/write modes on mixer | Automation |
855+
| ~~3.2~~ | ~~Automation read/write/touch/latch modes on mixer~~ | ~~Automation~~ DONE |
861856
| 4.3 | Quantize strength and swing | MIDI |
862857
| 4.4 | Transpose selected notes | MIDI |
863858
| 6.1 | Stem export | Export |

V1_FEATURE_SET_ROADMAP.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ This document defines the feature set needed for a completed FreeDaw v1, based o
99
| --------------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
1010
| Project lifecycle | New/open/save/save-as, autosave, crash recovery, unsaved-changes prompt, window title with dirty indicator | ~~No autosave, crash/session recovery, or close-with-unsaved-changes prompt~~ **DONE** |
1111
| Transport | Play/stop/record/loop toggle, BPM, time signature in `src/ui/transport/TransportBar.cpp` | No loop in/out range UI, no count-in/pre-roll, no punch in/out |
12-
| Timeline editing | Drag/resize/split/delete clips and drag-drop import in `src/ui/timeline/TimelineView.cpp` and `ClipItem.cpp` | No automation lanes, no marker lane, no comping/take lanes |
12+
| Timeline editing | Drag/resize/split/delete clips and drag-drop import in `src/ui/timeline/TimelineView.cpp` and `ClipItem.cpp`; automation lanes with envelope editing in `AutomationLaneItem.cpp` | No marker lane, no comping/take lanes |
1313
| Audio editing | Trim/fade/normalize/reverse/silence in `src/ui/audioclip/AudioClipEditor.cpp` and `AudioWaveformView.cpp` | No integrated time-stretch workflow for clip warping across timeline |
14-
| MIDI note editing | Note draw/select/move/resize, quantize, velocity lane in `src/ui/pianoroll/NoteGrid.cpp` and `VelocityLane.cpp` | No CC lanes, no MIDI channel chooser, no pitch-bend/aftertouch editing |
15-
| Mixer and routing | Channel strip controls + routing graph in `src/ui/mixer/ChannelStrip.cpp` and `src/ui/routing/RoutingView.cpp` | No automation controls surfaced from mixer for writing/reading envelopes |
14+
| MIDI note editing | Note draw/select/move/resize, quantize, velocity lane in `src/ui/pianoroll/NoteGrid.cpp` and `VelocityLane.cpp`; CC lane editor with point editing in `src/ui/pianoroll/CcLane.cpp` | ~~No CC lanes~~, no MIDI channel chooser, no pitch-bend/aftertouch editing |
15+
| Mixer and routing | Channel strip controls + routing graph in `src/ui/mixer/ChannelStrip.cpp` and `src/ui/routing/RoutingView.cpp`; per-track automation modes (Read/Touch/Latch/Write) with fader/knob visual tracking | ~~No automation controls surfaced from mixer for writing/reading envelopes~~ **DONE** |
1616
| Plugins and FX | VST3 scan/cache in `src/engine/PluginScanner.cpp`, effect chain and plugin editor UI in `src/ui/effects/` | No plugin blacklist UI, no custom scan path UI, VST3-only scan |
1717
| Export/render | Mix export, freeze, bounce in `src/engine/EditManager.cpp`; export dialog in `src/ui/dialogs/ExportDialog.cpp` | Export is WAV-only, no stem/per-track export workflow |
1818
| Device/performance UX | Audio settings dialog, live status bar, device persistence in `src/engine/AudioEngine.cpp` | ~~No audio settings panel; status bar shows static values~~ **DONE** |
@@ -24,12 +24,13 @@ This document defines the feature set needed for a completed FreeDaw v1, based o
2424

2525
### Must-have before v1 release
2626

27-
1. **Automation envelopes (core DAW expectation)**
28-
- Track automation lanes for volume, pan, mute.
29-
- Plugin parameter automation lanes.
30-
- Point add/move/delete and ramp editing on timeline.
27+
1. **Automation envelopes (core DAW expectation)** -- **DONE**
28+
- ~~Track automation lanes for volume, pan, and plugin parameters.~~
29+
- ~~Point add/move/delete, freehand draw, and curve shape editing on timeline.~~
30+
- ~~Read/Touch/Latch/Write modes per track with fader/knob visual tracking.~~
31+
- ~~Master channel automation support.~~
3132
2. **MIDI CC + channel fundamentals**
32-
- CC lane editor (minimum CC1, CC7, CC10, CC11 + arbitrary CC picker).
33+
- ~~CC lane editor (minimum CC1, CC7, CC10, CC11 + arbitrary CC picker).~~ **DONE**
3334
- Per-track or per-clip MIDI channel assignment (1-16).
3435
3. **Recording ergonomics baseline**
3536
- Loop in/out range handles in transport/timeline.
@@ -76,13 +77,13 @@ FreeDaw v1 is complete when all items below are true:
7677

7778
### MIDI creation workflow
7879

79-
- User can edit notes and velocity (already present) and also edit CC data in lanes.
80+
- ~~User can edit notes and velocity (already present) and also edit CC data in lanes.~~ **DONE**
8081
- User can select MIDI channel behavior per track or clip and get predictable playback/output.
8182

8283
### Mixing and automation
8384

84-
- User can automate at least volume, pan, mute, and one plugin parameter with visible envelopes.
85-
- Automation points persist after save/reload and render correctly in playback/export.
85+
- ~~User can automate at least volume, pan, mute, and one plugin parameter with visible envelopes.~~ **DONE**
86+
- ~~Automation points persist after save/reload and render correctly in playback/export.~~ **DONE**
8687

8788
### Reliability and data protection
8889

@@ -98,7 +99,7 @@ FreeDaw v1 is complete when all items below are true:
9899
## Suggested Execution Order
99100

100101
1. ~~Data safety (`unsaved prompt` + `autosave` + `recovery`) and audio settings panel.~~ **DONE**
101-
2. Automation lanes (engine model + timeline UI + persistence).
102+
2. ~~Automation lanes (engine model + timeline UI + persistence) and mixer automation modes.~~ **DONE**
102103
3. MIDI CC lanes and channel assignment.
103104
4. Loop in/out UI, metronome, and count-in.
104105
5. Stem export and plugin-management polish.

0 commit comments

Comments
 (0)