Docs file normalization.

This commit is contained in:
Johannes Findeisen 2026-11-06 15:20:20 +01:00
commit 619c2d0808
46 changed files with 3587 additions and 2579 deletions

View file

@ -1,44 +1,51 @@
# GUI guidelines
# GUI Guidelines
Use FLTK/C++ for windows, menus, dialogs, and the event loop. Keep all audio
engine and project-domain logic in C.
Main views:
- Sequencer: tracks, clips, ruler, playhead, selection, zoom and scrolling.
- Mixer: channels, faders, pan, mute/solo and meters.
- Modular graph: nodes, ports, connections, validation feedback.
- Transport: play/stop/record, tempo, meter, loop and position.
Use custom-drawn widgets where ordinary controls are not a good fit: timeline,
waveforms, piano roll, mixer strips and graph canvas. Keep drawing separate
from project mutation. Never call FLTK from the audio thread.
waveforms, piano roll, mixer strips and graph canvas. Keep drawing separate from
project mutation. Never call FLTK from the audio thread.
Visual direction: compact, high-contrast, restrained dark interface. Avoid
excessive animation and modal configuration. Recreate broad usability ideas,
not energyXT's exact artwork or proprietary resources.
excessive animation and modal configuration. Recreate broad usability ideas, not
energyXT's exact artwork or proprietary resources.
---
## Shell
The shell opens JACK on startup through `xtc_backend.h`. It never accesses
backend structures, processes samples, or calls JACK itself. Graph domain
data is owned by opaque C objects, manipulated only through the C API. All backend control calls run on the GUI thread; FLTK is never called
from an audio callback. No server is started and no audio ports are connected
by the GUI. The initially empty graph produces silence.
backend structures, processes samples, or calls JACK itself. Graph domain data
is owned by opaque C objects, manipulated only through the C API. All backend
control calls run on the GUI thread; FLTK is never called from an audio
callback. No server is started and no audio ports are connected by the GUI. The
initially empty graph produces silence.
- **Play / F5:** start the engine. **Stop / F8:** deactivate it. **Pause / F7:** hold playback. **Space:** toggle Play/Stop.
**To start / Home:** stop and seek to zero. Pause/Home are disabled while recording.
These advance/pause the sample-counted playhead; imported audio clips play through their graph source.
- **Reconnect / F6:** close the old client and open a fresh stopped client.
Use this after server loss or sample-rate changes. A failed close preserves
the handle and reports the failure instead of opening another client.
- **Play / F5:** start the engine. **Stop / F8:** deactivate it. **Pause / F7:**
hold playback. **Space:** toggle Play/Stop. **To start / Home:** stop and seek
to zero. Pause/Home are disabled while recording. These advance/pause the
sample-counted playhead; imported audio clips play through their graph source.
- **Reconnect / F6:** close the old client and open a fresh stopped client. Use
this after server loss or sample-rate changes. A failed close preserves the
handle and reports the failure instead of opening another client.
- **View menu / Ctrl+1, Ctrl+2, Ctrl+3:** switch between sequencer, mixer and
modular graph. Tabs provide the same view switching. Mixer, graph and sequencer editors are described below.
modular graph. Tabs provide the same view switching. Mixer, graph and
sequencer editors are described below.
- **File / Quit / Ctrl+Q** or the window close button: close the backend and
synchronize audio callbacks before hiding/destroying widgets. A failed close
leaves the window open for a retry. New/Open/Save actions are described below. About identifies the development milestone and version.
leaves the window open for a retry. New/Open/Save actions are described below.
About identifies the development milestone and version.
The indicator shows disconnected, ready, running, server lost, format changed
or process-error states. The status line shows rate, actual block size, mono
The indicator shows disconnected, ready, running, server lost, format changed or
process-error states. The status line shows rate, actual block size, mono
layout, processed block count, xruns and process result. Command errors remain
visible until a successful control action; periodic refresh does not erase them.
A GUI-owned 100 ms timer reads atomic snapshots and collects retired plans.
@ -54,41 +61,44 @@ process exit. Normal close/reconnect paths permit retry and release ownership
only after successful close. The entry point catches C++ exceptions before
process exit. Backend operations return C error codes throughout.
Tests: `make test-gui` runs real widgets/callbacks/timers against a fake C backend
under Xvfb, including control errors, startup without JACK, partially initialized
handles, server/format notifications, view switching, retrying close, and timer
removal. `make test-gui-jack` additionally requires a running JACK-compatible
server, tests repeated start/stop, reconnect and active-client close, and creates
no routes. Physical playback is outside this shell. See BUILD.md and the
integration test README for sanitizer limitations and keyboard smoke results.
Tests: `make test-gui` runs real widgets/callbacks/timers against a fake C
backend under Xvfb, including control errors, startup without JACK, partially
initialized handles, server/format notifications, view switching, retrying
close, and timer removal. `make test-gui-jack` additionally requires a running
JACK-compatible server, tests repeated start/stop, reconnect and active-client
close, and creates no routes. Physical playback is outside this shell. See
BUILD.md and the integration test README for sanitizer limitations and keyboard
smoke results.
## Modular editor
---
Open **Modular Graph** or press **Ctrl+3**. Add oscillator (440 Hz), gain (0.10),
pass-through meter or output nodes with the toolbar. Their parameters are fixed
presets in this milestone and are drawn on each node; parameter editing and
live meter display are not implemented. Connect oscillator → gain → meter →
output for a simple test chain. No sound reaches hardware until ports are
explicitly connected outside the GUI. Output nodes are required to render;
## Modular Editor
Open **Modular Graph** or press **Ctrl+3**. Add oscillator (440 Hz), gain
(0.10), pass-through meter or output nodes with the toolbar. Their parameters
are fixed presets in this milestone and are drawn on each node; parameter
editing and live meter display are not implemented. Connect oscillator → gain →
meter → output for a simple test chain. No sound reaches hardware until ports
are explicitly connected outside the GUI. Output nodes are required to render;
isolated sources and an empty graph produce silence.
Drag a node body/title to move it. Drag a circular output port to an input port
to connect. Click a node or wire to select it (yellow outline/wire), then press
Delete/Backspace or **Delete selection**. Deleting a node deletes its incident
wires. Escape cancels a drag preview. Canvas scrollbars pan the view; positions
are retained across edits/reconnect but not across application restart. There
is no graph zoom, multiselection or external hardware routing UI. Semantic
graph edits participate in project undo/redo; layout does not. The default
project supports 64 nodes; auto-layout can grow the scrollable canvas.
are retained across edits/reconnect but not across application restart. There is
no graph zoom, multiselection or external hardware routing UI. Semantic graph
edits participate in project undo/redo; layout does not. The default project
supports 64 nodes; auto-layout can grow the scrollable canvas.
Every semantic action becomes a C graph command. The window owns a C project containing the graph
handle and publishes the C-created candidate through the backend. Cycle,
invalid-direction, duplicate connection, missing-port, capacity and backend
failures are shown below the canvas; failed edits leave the graph unchanged.
Capacity feedback distinguishes the possible node limit/pending edit condition
and allows retry. Editing while stopped replaces the prepared plan without
starting playback. Editing with a disconnected startup backend stays local
until reconnect. A lost or changed live backend requires reconnect before
Every semantic action becomes a C graph command. The window owns a C project
containing the graph handle and publishes the C-created candidate through the
backend. Cycle, invalid-direction, duplicate connection, missing-port, capacity
and backend failures are shown below the canvas; failed edits leave the graph
unchanged. Capacity feedback distinguishes the possible node limit/pending edit
condition and allows retry. Editing while stopped replaces the prepared plan
without starting playback. Editing with a disconnected startup backend stays
local until reconnect. A lost or changed live backend requires reconnect before
further semantic edits. Moving/selecting nodes does not touch the engine.
The graph state line distinguishes offline, prepared, queued and active states.
@ -100,54 +110,59 @@ rejected capacity edit. Plan replacement can reset oscillator phase and is not
crossfaded. Render validation and active replacement tests are described in
tests/integration/README.md.
---
## Projects and sequencer
## Projects and Sequencer
File/New (Ctrl+N), Open (Ctrl+O), Save (Ctrl+S), and Save As
(Ctrl+Shift+S) use native file dialogs and the C persistence API. New/Open/Quit
offer Cancel/Discard when semantic edits are unsaved; save first to retain them.
Save As confirms overwrites. The title marks unsaved changes. Failed loads and
File/New (Ctrl+N), Open (Ctrl+O), Save (Ctrl+S), and Save As (Ctrl+Shift+S) use
native file dialogs and the C persistence API. New/Open/Quit offer
Cancel/Discard when semantic edits are unsaved; save first to retain them. Save
As confirms overwrites. The title marks unsaved changes. Failed loads and
backend submissions retain the old document. Loading parses before stopping
audio; installing a valid candidate stops and resets transport before compiling
and submitting. A later failure can leave the retained document stopped at zero.
Opening/New resets graph layout; graph positions are not saved. See PROJECT_FORMAT.md.
Opening/New resets graph layout; graph positions are not saved. See
PROJECT_FORMAT.md.
Sequencer offers Add track, Add region, Delete region/track, Zoom +/-. Select a
track header to add a one-bar region there at the cursor. Select a region to
delete it; deleting a selected track cascades to its regions. Delete also works
with canvas focus. Drag a region body to move it in time or between tracks;
drag either edge to trim within its original source bounds. Edits commit on
release with the selected snap grid; Escape cancels. There is no drag preview.
Undo, rename, tempo editing and additive clip selection are supported. Group
commands, clipboard and musical transforms are described in
with canvas focus. Drag a region body to move it in time or between tracks; drag
either edge to trim within its original source bounds. Edits commit on release
with the selected snap grid; Escape cancels. There is no drag preview. Undo,
rename, tempo editing and additive clip selection are supported. Group commands,
clipboard and musical transforms are described in
[MODERN_EDITING.md](MODERN_EDITING.md). Overlapping regions are permitted.
The scrollable canvas expands to cover the arrangement plus a margin; zoom
ranges from 24 to 384 pixels/quarter. Names, tempo and 4/4 meter are drawn.
A ruler click seeks while stopped (or positions the cursor when disconnected).
The 100 ms GUI refresh converts the backend's actual sample counter to ticks;
it never integrates wall-clock time. Play resumes and Stop pauses. Reconnect,
New and Open reset position. Add region creates silent metadata; imported WAV clips play through the
audio source node (see below). MIDI clips and notes are described below. The C model
supports a constant tempo; a tempo map and scheduler are future work.
ranges from 24 to 384 pixels/quarter. Names, tempo and 4/4 meter are drawn. A
ruler click seeks while stopped (or positions the cursor when disconnected). The
100 ms GUI refresh converts the backend's actual sample counter to ticks; it
never integrates wall-clock time. Play resumes and Stop pauses. Reconnect, New
and Open reset position. Add region creates silent metadata; imported WAV clips
play through the audio source node (see below). MIDI clips and notes are
described below. The C model supports a constant tempo; a tempo map and
scheduler are future work.
Tests cover C-model/persistence boundaries, GUI move/trim gestures and zoom,
save/reopen, failed load/submission rollback, sample-derived cursor updates,
and live JACK playhead advance/pause.
save/reopen, failed load/submission rollback, sample-derived cursor updates, and
live JACK playhead advance/pause.
---
## Audio workflow
## Audio Workflow
Use File/Import WAV (Ctrl+I) to add an audio clip at the playhead on the selected
track, or on a new Audio track. Record (Shift+F5) chooses a WAV destination and
captures JACK input until Stop finalizes and adds the take. No input routes are
created automatically. Save after Stop; the project references the external WAV.
Use File/Import WAV (Ctrl+I) to add an audio clip at the playhead on the
selected track, or on a new Audio track. Record (Shift+F5) chooses a WAV
destination and captures JACK input until Stop finalizes and adds the take. No
input routes are created automatically. Save after Stop; the project references
the external WAV.
Import creates an Audio clips graph source and output route if the source is
absent. Modular Graph offers Add audio source for explicit routing through gain
or meter nodes. All tracks currently share one mono timeline mix. Arrangement
edits stop playback; graph edits remain live outside recording. During recording,
edits, file actions, reconnect and close require Stop first.
edits stop playback; graph edits remain live outside recording. During
recording, edits, file actions, reconnect and close require Stop first.
Open/Play reports missing, unreadable or unsupported assets, preserving their
regions as silence. The backend status shows the unique issue count. Select a
@ -158,21 +173,26 @@ can block the GUI while reading, but never the audio callback.
See AUDIO_FILES.md for supported WAV formats, memory limits, musical placement,
recording overflow/partial-take recovery, external asset portability and the
software-only acceptance tests. Waveform drawing, input monitoring, recording
latency compensation and per-track graph inserts are not implemented.
Per-track gain/pan/mute/solo is available in the mixer below.
latency compensation and per-track graph inserts are not implemented. Per-track
gain/pan/mute/solo is available in the mixer below.
## Piano roll
---
## Piano Roll
Add MIDI clip creates a one-bar clip on the selected/first existing track at the
cursor. Select it and choose Piano roll (View/Piano roll, Ctrl+4). Click to draw,
drag a body to move pitch/time, drag its right edge to resize, and right-click
or Delete to remove. Notes use source ticks with 1/16 snapping; trimmed source
content is retained. Edits stop transport and are blocked during audio recording.
Panic/F9 silences held notes; Record continues to mean WAV audio capture.
Modular Graph offers Add instrument for explicit routing. Status includes MIDI
drops. See MIDI.md for voice limits, unsupported messages and live input routing.
cursor. Select it and choose Piano roll (View/Piano roll, Ctrl+4). Click to
draw, drag a body to move pitch/time, drag its right edge to resize, and
right-click or Delete to remove. Notes use source ticks with 1/16 snapping;
trimmed source content is retained. Edits stop transport and are blocked during
audio recording. Panic/F9 silences held notes; Record continues to mean WAV
audio capture. Modular Graph offers Add instrument for explicit routing. Status
includes MIDI drops. See MIDI.md for voice limits, unsupported messages and live
input routing.
## Mixer and editing
---
## Mixer and Editing
Mixer (Ctrl+2) now has a selectable track strip, gain/pan controls, mute/solo,
Output L/R peaks and editable gain/pan automation lanes. Mixer edits stop
@ -182,35 +202,42 @@ and redo up to 32 project edits; New/Open resets history. M/S and arrow keys
provide mixer shortcuts. See MIXER.md for exact controls, history rollback,
stereo port routing, automation semantics and prototype limits.
## Minimal composition workflow
---
## Minimal Composition Workflow
[WORKFLOW.md](WORKFLOW.md) walks through creating, arranging, saving, closing,
reopening and playing MIDI/audio with the GUI. New/Open select Sequencer;
Ctrl+3 still opens the modular graph. Stop retains its established position-hold
reopening and playing MIDI/audio with the GUI. New/Open select Sequencer; Ctrl+3
still opens the modular graph. Stop retains its established position-hold
behavior and finalizes recording; explicit Pause retains position without
finalizing a take (and is refused during recording). Home stops and returns to
zero. Failed candidate installation now refreshes the actual backend state
even when the previous document is retained.
zero. Failed candidate installation now refreshes the actual backend state even
when the previous document is retained.
`make test-workflow` uses a live JACK-compatible backend and Xvfb, with exact
stereo render comparisons across destruction/recreation of the GUI and live
playhead/meter/transport checks. `test-gui` covers stop/seek failure and recording
guards. No project files need manual editing for this workflow.
playhead/meter/transport checks. `test-gui` covers stop/seek failure and
recording guards. No project files need manual editing for this workflow.
## Timing and transitions
---
## Timing and Transitions
The GUI enables 5 ms source boundaries and master start/stop ramps. Ordinary
Pause/Stop now request a fade and show “stopping” until the timer collects its
acknowledgement and deactivates JACK. Recording Stop, Home, fault handling and
project installation retain immediate semantics. See
[AUDIO_QUALITY.md](AUDIO_QUALITY.md) for timing, overload/denormal behavior, latency
limits, test commands and the pending human-listening checklist.
[AUDIO_QUALITY.md](AUDIO_QUALITY.md) for timing, overload/denormal behavior,
latency limits, test commands and the pending human-listening checklist.
## Routing refinement
---
## Routing Refinement
Graph selection now reports edge counts, output reachability and external-input
fallback. Direction arrows, role colors, incident-wire highlighting and no-output
badges help inspect routes. View / Arrange graph by signal flow (L) is a layout
command; Edit / Insert unity gain in selected wire (I) is one undoable graph edit.
Left/Right selects nodes; Tab retains ordinary focus navigation. See [ROUTING.md](ROUTING.md) for summing, stereo-lane,
cycle, live publication and deferred grouping/template semantics.
fallback. Direction arrows, role colors, incident-wire highlighting and
no-output badges help inspect routes. View / Arrange graph by signal flow (L) is
a layout command; Edit / Insert unity gain in selected wire (I) is one undoable
graph edit. Left/Right selects nodes; Tab retains ordinary focus navigation. See
[ROUTING.md](ROUTING.md) for summing, stereo-lane, cycle, live publication and
deferred grouping/template semantics.