Phase 21: add filtered MIDI composition edits and triplet piano-roll grids
This commit is contained in:
parent
830b6e1914
commit
73fc5eea8d
12 changed files with 796 additions and 39 deletions
69
docs/MIDI.md
69
docs/MIDI.md
|
|
@ -14,9 +14,9 @@ are connected automatically. Connect a MIDI source to the backend's `midi_in`
|
|||
JACK port, and route audio output explicitly to hear it while Play is running.
|
||||
|
||||
The piano roll shows all 128 pitches and edits clip-source time. Click blank
|
||||
space to draw a one-beat note (velocity 100, channel 0); drag its body to move
|
||||
space to draw a one-beat note (velocity 100, filtered channel or channel 0); drag its body to move
|
||||
it, drag the right edge to resize, or right-click/Delete to remove it. Edits
|
||||
snap to 1/16 notes. Escape cancels a drag. Trimmed-out source notes remain editable
|
||||
snap to the configured grid (default 1/16). Escape cancels a drag. Trimmed-out source notes remain editable
|
||||
and are preserved. Arrangement/note edits stop playback and are blocked during
|
||||
audio recording. Save/Open preserves MIDI flags, notes and stable IDs.
|
||||
|
||||
|
|
@ -37,8 +37,9 @@ builds audio and MIDI candidates before committing the stopped backend state.
|
|||
|
||||
JACK events have sample offsets within the current block. Supported messages
|
||||
are complete note on/off (including velocity-zero note on) and CC120/123 on
|
||||
channels 0..15. Equal-offset events retain input order. Other messages are
|
||||
ignored; sustain, bend, program changes, running status and SysEx are unsupported.
|
||||
channels 0..15, plus CC7 volume, CC10 pan and CC64 sustain (see CONTROL.md).
|
||||
Equal-offset events retain input order. Bend, program changes, running status
|
||||
and SysEx are unsupported.
|
||||
At most 256 events are accepted per block. Malformed/overflowed input discards
|
||||
that block's events and triggers panic, with a MIDI-drop status counter.
|
||||
|
||||
|
|
@ -58,8 +59,8 @@ rejects more than 32 overlapping scheduled notes with CAPACITY. Such metadata
|
|||
can be saved by the C model, but GUI Open/Play rejects it until overlap is
|
||||
reduced. Immediate note-off/stealing can click; there is no envelope or limiter,
|
||||
and summed voices can exceed unity. Above-Nyquist pitches are silent.
|
||||
There is no per-track/channel instrument routing, velocity editor, MIDI recording,
|
||||
SMF import, undo or piano-roll zoom yet.
|
||||
There is no per-track/channel instrument routing, MIDI recording, SMF import
|
||||
or piano-roll zoom yet. Note edits participate in project snapshot undo/redo.
|
||||
|
||||
## Verification
|
||||
|
||||
|
|
@ -74,3 +75,59 @@ Physical MIDI devices, bridge/device loss behind an unchanged port, latency and
|
|||
long-running performance remain unverified. Panic/Stop provides manual recovery.
|
||||
|
||||
Phase 8 adds track mixing, automation and project undo/redo; see MIXER.md.
|
||||
|
||||
## Phase 21 composition commands
|
||||
|
||||
The piano-roll **Notes** menu exposes these commands. Shortcuts apply while the
|
||||
piano roll has focus; use the main window Edit menu for undo/redo.
|
||||
|
||||
| Command | Shortcut | Behavior |
|
||||
| --- | --- | --- |
|
||||
| Grid | G | 1, 120, 160, 240, 320, 480 or 960 ticks |
|
||||
| Filter | F | Channel -1 (all) or 0..15, inclusive pitch range 0..127 |
|
||||
| Velocity and channel | V | Set either property; -1 preserves it |
|
||||
| Quantize | Q | Snap starts to nearest configured grid; ties go later |
|
||||
| Transpose | T / Up / Down | Semitone count / one semitone up / down |
|
||||
| Repeat | Ctrl+D | Additional copies at a positive source-tick spacing |
|
||||
| Select filtered | Ctrl+A | Select every note matching the current clip filter |
|
||||
| Delete | Delete | Remove the single selected note or all filtered notes |
|
||||
|
||||
160 ticks is a sixteenth-note triplet; 320 is an eighth-note triplet.
|
||||
The grid governs drawing, drag movement and minimum resize duration. At 1-tick
|
||||
snap the visual grid remains 120 ticks to stay legible at the fixed zoom.
|
||||
The header shows current grid, channel/pitch filter and selection scope.
|
||||
Velocity also affects unselected note brightness. Preferences are session-only.
|
||||
|
||||
Click selects one visible note; Ctrl+A selects the whole filtered set. A click
|
||||
or filter change clears that set selection. Hidden notes cannot be mouse-edited.
|
||||
A channel filter also sets the channel for newly drawn notes. No lasso or
|
||||
arbitrary disjoint multi-selection is provided. Moving/resizing uses the mouse;
|
||||
V edits velocity/channel without changing timing, pitch or IDs. Quantization
|
||||
changes starts only, preserving durations and other properties. Repetition
|
||||
keeps originals and gives every copy a fresh stable ID; spacing need not equal
|
||||
note length, so both overlapping patterns and rests are possible. The existing
|
||||
clip source must have room for every result; extend it in Sequencer first if
|
||||
needed. Source notes outside the visible arrangement trim remain editable.
|
||||
|
||||
All batch edits validate before mutation. Invalid pitch/range, copy counts,
|
||||
capacity overflow or a note crossing the source boundary rejects the entire
|
||||
operation; notes are never silently clamped, merged or shortened. Unmatched
|
||||
notes, notes in other clips and unrelated properties are preserved. Each
|
||||
successful command records one undo step and stops playback before model edits;
|
||||
Play prepares the new engine plan. Undo/redo reinstalls the corresponding plan.
|
||||
These edits use the existing persisted note fields; format remains v7.
|
||||
|
||||
Scheduled notes occupy [start,end), with ends counted before starts at an equal
|
||||
sample for the 32-voice limit. Overlapping same-channel/pitch scheduled notes
|
||||
are independent sine voices; adjacent repetitions restart phase. Live repeated
|
||||
notes instead retrigger the matching channel/pitch voice, and a note-off releases
|
||||
that voice (or defers release under sustain). Equal-sample live on/off/control
|
||||
messages execute in caller/JACK order, with no implicit priority reordering.
|
||||
The renderer rejects malformed/unsorted/out-of-range events before touching
|
||||
output or runtime; raw velocity-zero note-ons decode to note-off.
|
||||
|
||||
`make test-composition` covers filters, property preservation, triplet rounding,
|
||||
repeats/fresh IDs, rejected batch rollback, capacity, undo snapshots, equal-offset
|
||||
live order, adjacent/overlapping notes, exact block partitions and seek chase.
|
||||
`make test-gui` covers mouse edits and the new commands with undo/redo and engine
|
||||
reinstallation. Listening and physical MIDI-device validation remain pending.
|
||||
|
|
|
|||
233
docs/ROADMAP.md
233
docs/ROADMAP.md
|
|
@ -458,6 +458,239 @@ or distro registration is performed. Independent human installation/usability,
|
|||
physical-device/endurance and listening acceptance remain pending and must be
|
||||
completed before claiming production qualification.
|
||||
|
||||
## Phase 21 — Advanced MIDI and Composition
|
||||
|
||||
### Goal
|
||||
Make MIDI composition expressive and efficient without turning the application into an unnecessarily complicated notation editor.
|
||||
|
||||
### Tasks
|
||||
- Improve piano-roll editing for note creation, selection, movement, resizing, and deletion.
|
||||
- Support configurable snap and grid resolution, including triplets where practical.
|
||||
- Add velocity editing and editing for supported MIDI note properties.
|
||||
- Support MIDI channel and note-range filtering where appropriate.
|
||||
- Improve quantization, transposition, duplication, and pattern repetition.
|
||||
- Ensure MIDI event ordering is deterministic, especially when note-off and note-on events share a timestamp.
|
||||
- Define handling for overlapping notes, repeated notes, and malformed MIDI events.
|
||||
- Add regression tests for MIDI editing and playback scheduling.
|
||||
|
||||
### Acceptance criteria
|
||||
- Common MIDI editing tasks can be completed without manually editing project files.
|
||||
- Editing preserves unrelated notes and event properties.
|
||||
- MIDI scheduling remains deterministic at buffer boundaries and under transport changes.
|
||||
- MIDI operations are covered by automated tests.
|
||||
|
||||
Implemented: transactional C filtered note transforms, nearest-grid quantization,
|
||||
velocity/channel edits, transposition, bounded fresh-ID repetition and deletion;
|
||||
piano-roll Notes menu, keyboard commands, configurable straight/triplet grids,
|
||||
channel/pitch filtering and filtered-set selection. Existing mouse move/resize
|
||||
and project undo/redo remain supported. Core and GUI regression tests demonstrate
|
||||
property/other-clip preservation, rollback, undo/redo, adjacent/overlapping notes,
|
||||
equal-offset caller ordering, exact block partitions and seek chase. See MIDI.md.
|
||||
No format change, MIDI capture, SMF import, lasso selection or piano-roll zoom;
|
||||
physical-device and listening validation remain pending.
|
||||
|
||||
Acceptance evidence:
|
||||
- [x] Menu/keyboard/mouse commands edit notes without project-file editing.
|
||||
- [x] Filtered batch tests preserve unmatched notes and unrelated properties.
|
||||
- [x] Exact scheduling tests cover buffer boundaries and transport seeks.
|
||||
- [x] Core composition and GUI undo/redo regressions exercise these operations.
|
||||
|
||||
## Phase 22 — Audio Clip Editing and Utility Operations
|
||||
|
||||
### Goal
|
||||
Provide focused, non-destructive audio editing tools for arranging and preparing recorded or imported material.
|
||||
|
||||
### Tasks
|
||||
- Support moving, trimming, splitting, duplicating, and deleting audio clips.
|
||||
- Define clip-boundary behavior, including fades and source offsets.
|
||||
- Add non-destructive clip gain and basic fade-in/fade-out controls.
|
||||
- Support time-stretching and pitch-shifting only after selecting a suitable implementation and quality target; otherwise document them as future work.
|
||||
- Ensure edits do not unexpectedly modify source audio files.
|
||||
- Add waveform display caching that never blocks the audio thread.
|
||||
- Test edits at project boundaries, source-file boundaries, and very short clip lengths.
|
||||
- Document which operations are destructive and non-destructive.
|
||||
|
||||
### Acceptance criteria
|
||||
- Basic clip editing is predictable and undoable.
|
||||
- Source files remain unchanged unless a documented destructive operation is explicitly invoked.
|
||||
- Clip boundaries do not produce unintended clicks from invalid offsets or discontinuities.
|
||||
- Editing and waveform generation never perform blocking work in the real-time audio callback.
|
||||
|
||||
## Phase 23 — Modular Workflow and Routing Refinement
|
||||
|
||||
### Goal
|
||||
Preserve the modular spirit of the application while making complex projects understandable and manageable.
|
||||
|
||||
### Tasks
|
||||
- Refine graph and routing views so signal paths are easy to inspect.
|
||||
- Make connections, disconnections, and invalid routing states clear.
|
||||
- Provide useful names and visual distinctions for tracks, instruments, effects, buses, and I/O ports.
|
||||
- Support track grouping or folders if the project model can represent them cleanly.
|
||||
- Add routing presets or reusable track templates only if they do not complicate the core model.
|
||||
- Define behavior for cycles and feedback paths; reject unsupported cycles explicitly.
|
||||
- Make graph changes transactional so failed edits do not leave partially updated routing.
|
||||
- Add tests for graph changes while playback is running.
|
||||
|
||||
### Acceptance criteria
|
||||
- Users can inspect and understand a project's signal path.
|
||||
- Invalid graph edits fail safely and leave the previous valid graph intact.
|
||||
- Graph updates follow the documented real-time synchronization strategy.
|
||||
- GUI routing concepts map cleanly to the public C engine API.
|
||||
|
||||
## Phase 24 — Mixing and Mastering Essentials
|
||||
|
||||
### Goal
|
||||
Provide the essential mixing controls needed to finish a small or medium-sized project.
|
||||
|
||||
### Tasks
|
||||
- Complete track and bus gain, pan, mute, solo, and metering behavior.
|
||||
- Define how solo states affect buses, sends, and sidechains.
|
||||
- Add peak meters with clear units and documented ballistics.
|
||||
- Add master-bus monitoring and clipping indicators.
|
||||
- Support routing to buses and auxiliary sends if the graph model supports them.
|
||||
- Make gain staging explicit and avoid hidden or surprising level changes.
|
||||
- Document meter tap points and whether values are pre-fader, post-fader, or post-effects.
|
||||
- Test mute, solo, pan, gain, and routing interactions.
|
||||
|
||||
### Acceptance criteria
|
||||
- Mixer controls behave consistently across tracks, buses, and master output.
|
||||
- Meter readings correspond to documented signal points and units.
|
||||
- Solo and mute behavior is covered by automated tests.
|
||||
- No mixer operation introduces allocations, locks, or other prohibited work in the audio callback.
|
||||
|
||||
## Phase 25 — Plugin and Instrument Usability
|
||||
|
||||
### Goal
|
||||
Make instruments and effects practical to use, manage, and diagnose in real projects.
|
||||
|
||||
### Tasks
|
||||
- Improve plugin discovery, insertion, removal, replacement, and ordering.
|
||||
- Show useful plugin identity and status information, including load failures.
|
||||
- Define parameter metadata, ranges, defaults, units, and formatting.
|
||||
- Support parameter reset and safe default values.
|
||||
- Preserve plugin state across save/load where the plugin API supports it.
|
||||
- Define behavior when a saved plugin is missing or incompatible.
|
||||
- Manage plugin UI lifetime separately from engine object lifetime.
|
||||
- Add tests for plugin lifecycle, state restoration, and failure paths.
|
||||
- Document plugin API versioning and compatibility expectations.
|
||||
|
||||
### Acceptance criteria
|
||||
- Users can identify and manage loaded instruments and effects without editing configuration files.
|
||||
- Missing or incompatible plugins produce actionable diagnostics and do not silently corrupt projects.
|
||||
- Plugin state restoration is tested for supported plugin types.
|
||||
- The engine remains safe if plugin initialization or processing fails, within the documented failure model.
|
||||
|
||||
## Phase 26 — Automation and Control Mapping
|
||||
|
||||
### Goal
|
||||
Enable repeatable changes to mix and instrument parameters over time, with clear timing and ownership rules.
|
||||
|
||||
### Tasks
|
||||
- Define a common parameter identity and metadata model.
|
||||
- Support automation lanes for a carefully selected set of parameters.
|
||||
- Define interpolation modes and behavior at clip boundaries.
|
||||
- Specify how automation interacts with live parameter changes and MIDI control.
|
||||
- Add control mapping for selected external MIDI controllers if feasible.
|
||||
- Schedule automation deterministically without allocating memory in the audio callback.
|
||||
- Define behavior when a target parameter or plugin is missing.
|
||||
- Test automation at buffer boundaries, during seeks, and across loop points.
|
||||
- Document precedence rules for automation, controller input, and direct user changes.
|
||||
|
||||
### Acceptance criteria
|
||||
- Supported parameters can be automated and saved in a project.
|
||||
- Playback produces deterministic automation values for a given project and transport position.
|
||||
- Missing targets fail safely and are reported to the user.
|
||||
- Automation processing meets the engine's real-time safety requirements.
|
||||
|
||||
## Phase 27 — Editing Workflow, Undo/Redo, and Usability
|
||||
|
||||
### Goal
|
||||
Make common editing actions quick, discoverable, and safe to reverse.
|
||||
|
||||
### Tasks
|
||||
- Audit user-visible editing operations for undo/redo support.
|
||||
- Implement command-based edits with explicit ownership and rollback behavior.
|
||||
- Group related low-level changes into one meaningful undo step.
|
||||
- Define undo behavior for operations affecting engine state or external files.
|
||||
- Improve keyboard shortcuts, selection behavior, focus handling, and context menus.
|
||||
- Use confirmation only for genuinely destructive or difficult-to-reverse actions.
|
||||
- Provide clear feedback for long-running operations and failures.
|
||||
- Add GUI tests or reproducible manual test procedures for critical workflows.
|
||||
- Keep presentation logic out of the core C engine.
|
||||
|
||||
### Acceptance criteria
|
||||
- Documented editing operations have predictable undo/redo behavior.
|
||||
- Undo and redo restore the project model and relevant engine state consistently.
|
||||
- Failed operations do not leave partial changes behind.
|
||||
- Common tasks can be completed using documented keyboard and mouse interactions.
|
||||
|
||||
## Phase 28 — Project Format, Compatibility, and Portability
|
||||
|
||||
### Goal
|
||||
Make project files robust, diagnosable, and maintainable across application versions and supported systems.
|
||||
|
||||
### Tasks
|
||||
- Version the project format and document its compatibility policy.
|
||||
- Validate project input before applying it to the live engine.
|
||||
- Handle missing media, plugins, and external dependencies with clear diagnostics.
|
||||
- Define relative-path, absolute-path, and media-relocation behavior.
|
||||
- Add safe migration routines for supported older versions.
|
||||
- Preserve unknown optional fields where practical, or document when they cannot be preserved.
|
||||
- Test malformed files, truncated files, oversized input, and invalid values.
|
||||
- Make saves atomic where the platform permits, using a temporary file and replacement strategy.
|
||||
- Document portability limits, including plugin and audio-backend dependencies.
|
||||
|
||||
### Acceptance criteria
|
||||
- Invalid project files are rejected safely without partially replacing the current project.
|
||||
- Save failures do not silently destroy the previous valid project file.
|
||||
- Version incompatibilities and missing dependencies are clearly reported.
|
||||
- Supported project versions have migration and regression tests.
|
||||
|
||||
## Phase 29 — Performance, Scalability, and Stress Testing
|
||||
|
||||
### Goal
|
||||
Establish measurable performance expectations and verify that larger projects remain stable.
|
||||
|
||||
### Tasks
|
||||
- Define representative test projects and target buffer sizes.
|
||||
- Measure audio callback duration, deadline misses, CPU use, memory use, and graph rebuild costs.
|
||||
- Test projects with increasing numbers of tracks, graph nodes, connections, MIDI events, and automation points.
|
||||
- Test long playback sessions and repeated start, stop, seek, and loop operations.
|
||||
- Stress-test device changes, plugin failures, missing media, and project reloads.
|
||||
- Use profiling to identify bottlenecks before introducing optimizations.
|
||||
- Verify that the real-time callback does not allocate, block on mutexes, perform file I/O, or wait on GUI work.
|
||||
- Document expected limits and known performance bottlenecks.
|
||||
- Add sanitizers and static analysis to regular development builds where supported.
|
||||
|
||||
### Acceptance criteria
|
||||
- Performance is measured against documented test cases, not subjective impressions alone.
|
||||
- Stress tests can run repeatedly and produce reproducible results.
|
||||
- No known real-time safety violation remains in the engine's own callback path.
|
||||
- Performance regressions can be detected by repeatable tests or benchmark reports.
|
||||
|
||||
## Phase 30 — Release Engineering, Packaging, and Maintenance
|
||||
|
||||
### Goal
|
||||
Turn the application into a maintainable release that users can build, install, run, and troubleshoot.
|
||||
|
||||
### Tasks
|
||||
- Define supported operating systems, compiler versions, and audio backends.
|
||||
- Document build dependencies and provide clear build and test commands.
|
||||
- Add install and uninstall targets that respect `PREFIX` and standard directory variables.
|
||||
- Provide appropriate package metadata and desktop integration where relevant.
|
||||
- Verify installation paths for binaries, libraries, headers, resources, documentation, and example projects.
|
||||
- Add version reporting and a concise diagnostic mode where useful.
|
||||
- Prepare release notes, known limitations, and upgrade guidance.
|
||||
- Test clean builds from a fresh checkout and installation into a staging directory.
|
||||
- Define a release checklist covering tests, warnings, packaging, and project compatibility.
|
||||
- Document how users can report reproducible bugs and how maintainers should triage them.
|
||||
|
||||
### Acceptance criteria
|
||||
- A clean checkout can be built and tested using documented commands.
|
||||
- Installation works with a configurable prefix and does not overwrite unrelated user files.
|
||||
- The release includes documentation, known limitations, and a reproducible version identifier.
|
||||
- The project has a repeatable process for preparing and validating releases.
|
||||
|
||||
---
|
||||
|
||||
## Recommended Execution Order
|
||||
|
|
|
|||
|
|
@ -96,3 +96,12 @@ core files may contain media paths and audio memory; share only what you intend.
|
|||
Report bugs following MAINTENANCE.md, including whether the issue reproduces
|
||||
without plugins. Physical listening and independent human install/usability
|
||||
acceptance remain pending.
|
||||
|
||||
## MIDI composition
|
||||
|
||||
In Piano roll, use the Notes menu for grid (including triplets), channel/pitch
|
||||
filters, velocity/channel, quantization, transposition and pattern repetition.
|
||||
Click selects a single note; Ctrl+A selects all filtered notes. Ctrl+D repeats
|
||||
that selection at a chosen spacing within the existing clip source. Up/Down
|
||||
transposes by a semitone. Commands are undoable through the main Edit menu.
|
||||
See [MIDI.md](MIDI.md#phase-21-composition-commands) for shortcuts, timing and limits.
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ Duplicate, Rename and Delete. Invalid/capacity edits retain the existing model.
|
|||
|
||||
View/Snap selects 1, 120, 240 (default), 480 or 960 ticks. It affects ruler seeks,
|
||||
clip moves and trims; 1 tick is the finest grid. Existing +/- zoom and scrollbars
|
||||
retain their behavior. Piano roll and mixer lanes retain their documented 240-tick
|
||||
retain their behavior. Piano roll has its own configurable grid (see MIDI.md); mixer lanes retain their 240-tick
|
||||
grid. Grid/zoom/selection are session UI preferences, not undoable music edits.
|
||||
Escape cancels a drag; Delete affects the focused editor; text fields keep their
|
||||
own editing keys. Commands are named in menus/tooltips and timeline focus accepts
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue