Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Maolan

Open source digital audio workstation built in Rust for recording, MIDI editing, automation, routing, and modern production workflows.

Maolan is a free, open-source DAW written in Rust. It prioritizes transparency, performance, and community-driven development.

Inspect the code. Build custom features. Contribute improvements. Own your tools.

  • 100% open source under a permissive license
  • Built with Rust for safety and performance
  • Community-driven development and improvements
  • Forever free, no licensing fees

Quick Start

git clone https://github.com/maolan
cd maolan
cargo run --release

Key Capabilities

Multi-Track Audio & MIDI

Record and arrange unlimited audio and MIDI tracks with precise timing and flexible mixing.

Piano Roll MIDI Editing

Intuitive piano roll interface for composing, editing, and refining MIDI performances.

Automation & Envelopes

Create track and plugin automation for volume, balance, mute, and loaded CLAP, VST3, or LV2 parameters. Save session and track templates for repeatable setups.

Plugin Hosting & Routing

Load CLAP, VST3, and LV2 plugins, create complex routing chains, and design custom signal flows with explicit audio, MIDI, and sidechain paths.

Export & Format Support

Export mixdowns or stems to WAV, MP3, OGG, and FLAC with normalization and master-limiter options saved in the session.

Autosave & Recovery

Automatic project backups and recovery features protect your work from unexpected interruptions.

Complete Production Workflow

  1. Recording: capture audio and MIDI from microphones, instruments, and controllers.
  2. Editing and composition: shape clips, notes, harmonies, and arrangements with piano-roll tools.
  3. Plugin and routing: load CLAP, VST3, and LV2 plugins and connect explicit audio, MIDI, and sidechain paths.
  4. Automation: write volume, pan, send, and plugin automation across the timeline.
  5. Mixing and mastering: balance levels and processing for a final production-ready session.
  6. Export: render full mixes or stems to standard delivery formats.

Open Source & Community Driven

Maolan is open source because audio production tools should be transparent, accessible, and shaped by their users.

You can inspect the code, understand how features work, and contribute improvements directly.

  • Contribute code to core features and plugins.
  • Report bugs and propose improvements.
  • Write documentation and tutorials.
  • Build extensions for your own workflow.

Project Stats

ItemValue
GitHubgithub.com/maolan
LicenseBSD-2-Clause
LanguageRust
StatusActive Development

Frequently Asked Questions

Is Maolan free?

Yes. Maolan is completely free and open source with no licensing fees, subscriptions, or paywalls.

Which platforms are supported?

Maolan supports Linux, FreeBSD, macOS, and Windows.

  • Linux and FreeBSD builds run on Wayland when available and fall back to X11 (Xorg) when Wayland is unavailable. Plugin UI embedding still uses X11, so an X11 server must be reachable even under Wayland (for example via XWayland).
  • macOS uses the native host path.
  • Windows uses WASAPI for audio and the Win32 API for windowing.

Which plugin formats are supported?

Maolan supports CLAP, VST3, and LV2 on Linux and FreeBSD. macOS and Windows builds support CLAP and VST3. LV2 remains Unix-only. All supported formats use per-process plugin hosting for crash isolation.

How does autosave and recovery work?

Maolan writes autosave snapshots every 15 seconds into .maolan_autosave/snapshots/ beside the live session, for example:

<session>/.maolan_autosave/snapshots/<timestamp>/

When opening a session, Maolan can detect a newer snapshot, preview the differences, and recover the latest valid autosave first.

Does Maolan support templates?

Yes. Session templates preserve track structure, routing, plugin graphs, plugin state, metadata, and export settings. Track templates preserve one track’s settings, plugin graph, plugin state, and that track’s connections, while intentionally leaving out audio and MIDI clips.

How can I contribute?

There are many ways to contribute to Maolan:

  • Code: Submit pull requests for features, bug fixes, or improvements
  • Documentation: Help improve guides, tutorials, and API docs
  • Testing: Report bugs, test features, and provide feedback
  • Design: Contribute UI/UX improvements and design ideas
  • Community: Help other users, answer questions, and promote the project

Visit the GitHub repository to get started. All contributors are welcome!

Can I reuse it in my Rust project?

Maolan is a two-part project: engine and GUI. The engine is independent of the GUI and can be reused in your own Rust project.

cargo add maolan_engine

Getting Started

Maolan is currently available for FreeBSD, Linux, macOS, and Windows.

Download

FreeBSD

Install from packages:

pkg install maolan

Linux

Download the x86_64 Fedora, Debian, and Ubuntu package from the release page:

github.com/maolan/maolan/releases/tag/0.2.3

Windows

Download the x86_64 installer (EXE) for Windows 10 and 11 from the release page:

github.com/maolan/maolan/releases/tag/0.2.3

macOS

There is no prebuilt macOS installer yet. Build Maolan from source on macOS following the repository instructions.

Build from Source

Maolan is open source. If you prefer to build manually or run on macOS, clone the repository and build with Cargo:

git clone https://github.com/maolan
cd maolan
cargo run --release

The main application is in the maolan/ directory. The repository root is a multi-crate project directory, not a single Cargo workspace, so build commands must be run from the relevant crate directory:

cd maolan
cargo build --workspace
cargo run

Release build

cd maolan
cargo build --workspace --release

Platform prerequisites

  • Linux / FreeBSD: pkg-config, JACK/ALSA dev packages, liblilv-dev, libsuil-dev, libgtk2.0-dev, FFmpeg libraries, LLVM/Clang (for bindgen).
  • Windows: Visual Studio Build Tools, LLVM/Clang, NSIS, vcpkg packages (sentencepiece:x64-windows), FFmpeg NuGet package. See maolan/scripts/build.ps1 and plugins/build.ps1 for the automated setup.
  • macOS: Xcode / Command Line Tools, CoreAudio frameworks.

Next Steps

Maolan Features

Last updated: 2026-07-09

Maolan is a modern open-source digital audio workstation designed for flexible music production, deep MIDI editing, powerful routing, and transparent development.

Core DAW Workflow

  • Multi-track audio + MIDI session editing
  • Track selection, reordering, resizing, and rename
  • Session template save/load
  • Track template save/load
  • Session save/open/save-as
  • Recent session tracking
  • Session metadata editing:
    • Author
    • Album
    • Year (unsigned)
    • Track number (unsigned)
    • Genre

Clip Editing

  • Audio clip and MIDI clip placement on timeline
  • Clip select/multi-select and marquee selection
  • Clip drag-and-drop move/copy across tracks
  • Clip group / ungroup on same-track, same-type selections
  • Nested clip groups preserved on save/load and restore on ungroup
  • Clip edge resize (left/right); MIDI clips can be extended past their content length (empty tail), audio clips are bounded by source length
  • Clip fade-in/fade-out resize
  • Clip mute/unmute
  • Clip rename
  • Clip middle-click split at cursor/snap point
  • Grouped clips cannot be split until ungrouped
  • MIDI clip double-click opens piano roll
  • Audio clip double-click opens per-clip plugin graph on Unix
  • Per-clip FX/plugin graph for audio clips:
    • Separate from the track plugin graph
    • Stored per clip in session data
    • Applies after grouped-child summing and clip fades in the current render path
    • Supports CLAP, VST3, and LV2 on supported Unix builds
  • Audio clip pitch-correction editor
  • Pitch-correction workflow:
    • Open from the audio clip context menu when transport is stopped
    • Analyze source material with per-session cached pitch scans for fast revisits
    • Reopen existing clip correction without re-analyzing when correction data is already saved on the clip
    • Tune detection granularity using frame-likeness (0.05–2.00) merge behavior
    • Manual pitch-segment retargeting with click, shift-click, marquee select, and grouped vertical drag editing
    • Double-click snap-to-nearest-note for one or many selected pitch segments
    • Local pitch-correction undo/redo history while editing
    • Adjustable inertia (0–1000 ms) for smoother pitch transitions between segments
    • Optional formant compensation in render path
    • Apply pitch correction from full clip or selected source offset/length window
    • Non-destructive clip workflow: edits stay local to the editor until Apply writes them back to the clip
    • Real-time pitch-shift playback after Apply
    • Offline pitch-corrected freeze preparation using timestretch preview renders
  • Audio warp markers with reset / half-speed / double-speed helpers

Folder Tracks

  • Folder tracks for hierarchical track organization
  • Collapsible/expandable folder view in the track list
  • Child tracks route through the folder track and are connectable to folder plugins
  • Folder track plugin graph for processing the summed child output
  • Child strips in the mixer and live view show highlighted top and bottom edges when their immediate parent folder is selected; the far-right child also gets a highlighted right edge
  • Track-to-folder plugin connections and disabled folder-output feeds
  • Folder track templates that save the full child subtree recursively

Timeline Markers and Arrangement Aids

  • Per-track editor markers
  • Marker create / rename / move / delete workflow
  • Snap-aware marker placement and marker dragging
  • Snap-to-clip start/end for clips, loop, punch, and markers
  • Ruler playhead seek
  • Loop range set/clear
  • Punch range set/clear

Take Lanes and Comping

  • Overlap-based take lane stacking
  • Set active take
  • Cycle to next active take
  • Unmute all takes in range
  • Take lane pin/unpin
  • Take lane lock/unlock
  • Take lane move up/down
  • Dedicated Comp tool with swipe comping

Automation

  • Track automation lanes:
    • Volume
    • Balance
    • Mute
  • Plugin automation lanes:
    • CLAP parameters
    • VST3 parameters
    • LV2 parameters (Unix)
  • Lane point insert/delete/edit
  • Automation ramp drawing
  • Automation lane editing with MIDI-style gestures (right-drag to draw ramps, click to insert points)
  • Automation modes:
    • Read
    • Touch
    • Latch
    • Write
  • Automation writeback from manual control changes
  • Plugin automation lane creation from loaded plugin parameters

Modulators

  • LFO-style modulators per session
  • Modulator shapes: Sine, Triangle, Saw, Square, Sample & Hold
  • Rate modes: Hz or musical divisions (beat, bar, etc.)
  • Per-modulator phase offset and enable toggle
  • Assign modulators to track parameters, plugin parameters, and MIDI controllers
  • Per-assignment min/max range scaling via the modulator target dialog
  • Modulators pane for creating, selecting, and editing modulators

Piano Roll / MIDI Tools

  • Note editing and selection
  • Velocity/controller editing
  • SysEx point create/edit/move/delete
  • Quantize
  • Humanize (time + velocity)
  • Groove (swing)
  • Scale snap
  • Chord generation
  • Legato
  • Velocity shaping
  • MIDI note snapping
  • Configurable scale root / major-minor mode
  • Configurable chord type
  • Configurable groove, humanize, and velocity-shape amounts

Timing and Transport

  • Tempo and time-signature timeline editing
  • Tempo/time-signature points add/move/delete/duplicate/reset
  • Numeric tempo/time-signature input with validation
  • Play/pause/stop/record transport control
  • GUI transport shortcuts for rewind-to-start/end, session record arm toggle, and panic
  • CLI transport shortcuts for rewind-to-start/end and panic
  • Toolbar panic button for hardware MIDI outputs (CC64=0, CC120=0, CC123=0)
  • Metronome enable/disable with visual icon
  • Clip playback enable/disable at transport level

Step Recording

  • Step recording mode in the piano roll
  • Toggle step recording from the MIDI editor toolbar (Step button)
  • Each incoming MIDI note is inserted at the step cursor and advances the cursor by the current MIDI snap interval
  • Step cursor drawn in the piano roll while the mode is active

Live Session View

  • Clip-launch grid modeled after Ableton Live
  • Switch between Workspace and Session view with Tab or the toolbar
  • Each row is a track; each column is a scene
  • Slots reference arrangement clips by stable clip ID
  • Launch/stop slots with click or Return
  • Launch scenes by clicking the Master column scene slots; the clicked scene is selected (while stopped, it starts on the next play; while playing, it launches when the current scene finishes)
  • Per-scene tempo changes on launch
  • Stop all clips with Shift+Space or the master stop column
  • Move, duplicate, and copy slot references between slots and the arrangement
  • Assign arrangement clips to session slots
  • Clear a slot’s clip with middle-click on the slot
  • Child strips show highlighted top and bottom edges when their immediate parent folder is selected; the far-right child also gets a highlighted right edge (same cue as the mixer)
  • Import the arrangement into the session grid
  • Record session clips into the arrangement (Rec to Arr)
  • Record directly into a slot
  • Scene options: rename, set color, set per-scene tempo, change launch quantization
  • Track strip with mute, solo, arm, volume, and pan controls

Freeze / Commit / Flatten

  • Per-track freeze/unfreeze
  • Freeze rendering with progress + cancel
  • Reversible frozen backups
  • Flatten frozen track (keep rendered audio, drop backups)
  • Freeze guardrails around mutable track operations

Routing and Mixing

  • Track controls:
    • Arm
    • Mute
    • Solo
    • Input monitor
    • Disk monitor
    • Phase invert
  • Aux return creation from selected tracks
  • Aux send controls:
    • Level adjust
    • Pan adjust
    • Pre/Post fader toggle
  • Track audio/MIDI passthrough defaults
  • Per-track plugin graph routing for:
    • Audio
    • MIDI
    • Sidechain / auxiliary plugin ports
  • Plugin window lifecycle and focus management

Plugins and Integration

  • CLAP plugin scan/load/unload/state restore/UI
  • VST3 plugin scan/load/unload/state restore/UI
  • LV2 plugin scan/load/unload/state restore/UI (Unix)
  • Plugin graph and per-track routing management
  • Mixed plugin graph session/template restore
  • Plugin parameter automation for loaded plugins
  • Offline plugin bounce path for freeze/export workflows
  • Plugin blocklist (~/.config/maolan/plugin-blocklist.json) to hide problematic plugins from scans

Export and Render

  • Mixdown and stem export (selected tracks)
  • Stem modes:
    • Pre-fader
    • Post-fader
  • Real-time fallback render mode
  • Export master limiter + dBTP ceiling
  • Normalization modes:
    • Peak
    • Loudness
  • Multi-format export in one run:
    • WAV
    • MP3 (via ffmpeg)
    • OGG (Vorbis, via ffmpeg)
    • FLAC
  • Dither options for integer PCM export:
    • None
    • Rectangular
    • Triangular (default)
  • Codec settings:
    • MP3 mode (CBR/VBR) + bitrate
    • OGG quality
  • Metadata tagging on supported formats:
    • MP3 (ID3 fields used by current encoder path)
    • OGG Vorbis comments

Control Surface and OSC

  • mixosc integration for OSC-based mixing control
  • Behringer X32 dedicated view

AI Audio Generation

  • HeartMuLa text-to-audio generation through maolan-generate
  • Prompt / lyrics driven generation with optional style tags
  • Burn backend options:
    • CPU
    • Vulkan
  • Model options:
    • happy-new-year
    • RL
  • Burn generation controls:
    • CFG scale
    • Steps
    • Top-k
    • Temperature
    • ODE steps
    • Decoder seed
    • Output --length in milliseconds
  • Decode-only mode from a saved frames JSON
  • Decode-only CPU worker override with --decode-threads
  • Hugging Face cache-backed model resolution for the current Burn repos:
    • maolandaw/HeartMuLa-happy-new-year-burn
    • maolandaw/HeartMuLa-RL-oss-3B-20260123
    • maolandaw/HeartCodec-oss-20260123-burn
  • Local model directory override with --model-dir

Example maolan-generate invocation:

cargo run -p maolan-generate --release -- \
  --model happy-new-year \
  --backend vulkan \
  --tags "ambient, cinematic, downtempo" \
  --length 12000 \
  --cfg-scale 1.5 \
  --topk 50 \
  --temperature 1.0 \
  --ode-steps 10 \
  --output output.wav \
  --lyrics "stars drift over the late train home"

Expected model assets:

  • HeartMuLa repo: heartmula.bpk, tokenizer.json, gen_config.json
  • HeartCodec repo: heartcodec.bpk

Media Management and File References

  • Collect/consolidate external media and plugin file references into the session’s data/ directory
  • Delete unused session media files from audio/, midi/, peaks/, and pitch/
  • Clips deleted from tracks are kept in a session-level unused pool (shown in the Clips pane) until File → Delete unused files removes them permanently
  • CLAP and LV2 file-reference support: plugins can declare external file references and Maolan updates them to session-relative data/ paths on consolidate
  • Consolidation makes sessions safer to move or share

Session Safety and Recovery

  • Dirty-state tracking
  • Close guard for unsaved changes
  • Periodic autosave snapshots
  • Startup autosave recovery prompt
  • Recover latest or older autosave snapshot
  • Recovery preview summary
  • Fallback to older snapshots on recovery failure
  • Startup recovery hint from last opened session

Diagnostics and Tooling

  • MIDI mappings report
  • MIDI mappings import/export/clear-all
  • Preferences saved to ~/.config/maolan/config.toml
  • Recent sessions menu

MIDI Learn and Control Surface Features

  • Track MIDI learn targets:
    • Volume
    • Balance
    • Mute
    • Solo
    • Arm
    • Input monitor
    • Disk monitor
  • Global MIDI learn targets:
    • Play/Pause
    • Stop
    • Record toggle
  • Mapping persistence in session
  • Collision/conflict protection

Widgets and UI Components

  • arch_slider with adjustable arc shape
  • Slider on_release option for both horizontal and vertical variants
  • Stretchable ticks and meters that fill available space

Platform Notes

  • Linux and FreeBSD builds support CLAP, VST3, and LV2.
  • Windows builds support WSAPI backend, CLAP, and VST3.
  • macOS builds refresh CLAP and VST3 plugin support paths; LV2 is Unix-only in the current codebase.
  • Linux and FreeBSD builds run on Wayland when available and fall back to X11 (Xorg) when Wayland is unavailable.
  • Plugin UI embedding on Unix still uses X11, so an X11 server must be reachable even under Wayland (for example via XWayland).
  • FreeBSD roadmap notes still mark MIDI 2.0 as N/A.

Known Boundaries

  • Plugin compatibility is still a real-world host-interop concern, especially across unusual plugins.
  • Many core behaviors are unit-tested, but editor-hosting and plugin-integration paths are still more integration-heavy than fixture-heavy.

Maolan Workflow

A practical map of how Maolan sessions move from track setup and plugin routing to autosave recovery, diagnostics, templates, and final export.

Last updated: 2026-07-09

Runtime and Platform Behavior

  • Linux and FreeBSD builds run on Wayland when available and fall back to X11 (Xorg) when Wayland is unavailable.
  • Plugin UI embedding on Unix still uses X11, so an X11 server must be reachable even under Wayland (for example via XWayland).
  • macOS builds support CLAP and VST3, but not the Unix LV2 host path.
  • Plugin discovery runs automatically on startup:
    • Linux / FreeBSD: LV2, VST3, CLAP
    • macOS: VST3, CLAP
  • Plugin discovery path overrides:
    • CLAP_PATH: additional CLAP scan roots (path-list format, platform separator)
    • VST3_PATH: additional VST3 scan roots (path-list format, platform separator)
  • CLAP discovery currently scans recursively and recognizes plugin binaries by extension:
    • .clap
    • .so
    • .dylib
    • .dll
  • When using CLAP_PATH, point it at a dedicated plugin directory that only contains plugin binaries.
    • Example (Linux/FreeBSD): CLAP_PATH=/home/user/plugins
    • Avoid broad build output roots when possible (for example full Cargo target trees) to reduce unrelated binary probing.
  • Passing --log-level <level> enables tracing output to stderr. Valid levels: none, info, warning, error, debug.

Audio Device Filtering

The hardware preference dialog filters devices by direction:

  • Output device lists show only devices that report output support.
  • Input device lists show only devices that report input support.
  • Devices that only support one direction no longer appear in the opposite list.

Plugin Blocklist

Maolan maintains a plugin blocklist at:

~/.config/maolan/plugin-blocklist.json

The blocklist hides plugins from the plugin browser and causes the scanner to skip them entirely during system scans, so a known-bad plugin cannot crash maolan-plugin-host --scan. You can add entries manually, or the DAW can add them automatically when a single-plugin scan fails, the scanner reports warnings or errors for a plugin, or the scanner host crashes.

A blocklist entry uses the plugin path as the key:

{
  "entries": [
    {
      "path": "/usr/lib/clap/CrashingPlugin.clap",
      "error": "scanner exited with code ...",
      "timestamp": "2026-06-30T11:14:01+00:00"
    }
  ]
}

Match rules per format:

  • CLAP and VST3: match the full plugin file path (path field in the scan result).
  • LV2: match either the bundle_uri (e.g. file:///usr/lib/lv2/SomePlugin.lv2/) or the plugin uri.

How completely the blocklist protects the scanner depends on the format:

  • CLAP and VST3: the scanner skips the bundle before loading or inspecting it, so the bad code never runs.
  • LV2: the scanner filters blocklisted plugins after the LV2 world has loaded and parsed the bundle. The plugin is hidden from the UI, but a crash inside the LV2 discovery layer could still happen before the filter runs.

Restart Maolan after editing the file. The status message after plugin discovery reports how many plugins were loaded and how many were blocklisted.

Configuration File

Maolan stores UI and preference state in:

~/.config/maolan/config.toml

Current persisted keys:

  • font_size
  • mixer_height
  • track_width
  • osc_enabled
  • default_export_sample_rate_hz
  • default_snap_mode
  • default_audio_bit_depth
  • default_output_device_id
  • default_input_device_id
  • recent_session_paths

If the file does not exist, Maolan creates it on startup with defaults.

Session Directory Layout

A saved session is a directory containing:

  • <branch>.json: main project state for the current branch (default: main.json)
  • session.json: Live Session View scene and slot data
  • audio/: imported or rendered audio stored in-session
  • midi/: copied MIDI files used by clips
  • peaks/: cached waveform peak data written on save
  • pitch/: cached pitch-analysis JSON files keyed by source clip path + source window
  • plugins/: plugin-related session assets
  • data/: consolidated external audio, MIDI, and plugin file references
  • .maolan_commits/<branch>/<timestamp>.json: commit history created on every save
  • .maolan_autosave/snapshots/: autosave snapshots

The session JSON persists:

  • tracks, clips, and track connections
  • clip group membership as recursive grouped_clips
  • per-audio-clip plugin graph state in plugin_graph_json
  • clip pitch-correction settings and saved pitch-segment targets
  • plugin graph topology and plugin state
  • session metadata
  • transport state, tempo points, and time-signature points
  • export dialog settings
  • global MIDI learn bindings
  • selected UI sizing values

Routing and Signal Flow

Maolan uses a per-track plugin graph rather than a fixed insert chain. Audio and MIDI paths are explicit, so the graph itself is the workflow.

Track Graph Model

New tracks start with passthrough audio routing from input to output, plus MIDI passthrough on the first input/output path.

Loading a plugin does not rewrite existing connections. The graph decides what actually receives or emits signal.

Audio clips on supported Unix builds can open their own plugin graph. If a clip has no saved graph yet, Maolan seeds a default passthrough clip graph first.

Folder tracks have their own plugin graph. Child tracks route into the folder graph, and child outputs can connect to folder plugins or directly to the folder output.

Main ports and extra auxiliary or sidechain ports are shown separately so unusual bus layouts remain visible.

MIDI input and output are explicit too. If a plugin emits MIDI, it must be routed onward to keep events moving.

Typical Graph Paths

Serial insert:

Track Input -> Plugin A -> Plugin B -> Track Output

Sidechain:

Keep the main audio input connected to the plugin’s main input, then route the source track or upstream output into the orange sidechain input separately.

MIDI instrument / effect:

Connect MIDI source to the plugin, then wire the plugin’s audio output to the next stage or track output. Route MIDI output explicitly if the plugin generates events.

Grouped audio render order:

Child clips render first, then group-level fades are applied, and finally the group clip plugin graph is processed.

Live Session View

The Session View (switch to it with the Live toolbar button or Tab) is a clip-launch grid modeled after Ableton Live. Each row is a track and each column is a scene. Slots reference arrangement clips by their stable clip ID, so edits to the arrangement clip are reflected in the session.

Switching between Workspace and Session view never stops playback. Transport controls hand over between the two: pressing play in one view while the other is playing stops the current playback and starts the pressed view’s playback, while pause and stop pressed in either view stop whatever is playing.

Session data is stored in session.json inside the session directory and includes the scene list and slot references. The arrangement (<branch>.json) is the source of truth for clip content; removing an arrangement clip that a slot references moves the clip to the unused pool, and the slot keeps playing it from there until the slot is cleared or the clip is deleted via File → Delete unused files.

Commands:

  • Launch/Stop slot: click a slot, or press Return on the selected slot. Each slot carries a play mark, a stop mark, or neither (right-click clears the mark); marked slots launch or stop their track on scene changes.
  • Launch scene: click a scene slot in the Master column. Clicking always selects that scene: while the live session is stopped, the selected scene (shown with a blue border) is the one the play button starts; while the live session is playing, the selected scene launches when the longest currently playing clip finishes its current pass. Clicking a different scene slot simply moves the selection, replacing any pending launch — clicking the currently playing scene re-triggers it at the end of its pass. On the switch, each track follows its slot in the new scene — play-marked slots launch, stop-marked slots stop — and a slot with neither mark inherits from the same track’s slot in the previously playing scene (play if that slot was play-marked — the previous scene’s clip keeps playing, or starts when the track is silent — stop if it was stop-marked, and keeps doing whatever it was doing when that slot is also unmarked). The currently playing scene’s slot is filled green with a green border. If the scene has a per-scene tempo set, the global tempo changes when the scene launches (immediate launches only).
  • Stop all clips: press Shift+Space, click the Stop All button in the master column, or use the slot context menu.
  • Stop track clips: click the stop square in the master column for that track row.
  • Move slot reference: drag a slot that references a clip onto another slot in the grid. This moves the clip reference; the arrangement clip itself is not affected.
  • Duplicate slot: right-click a slot that references a clip and choose Duplicate. This copies the clip reference to the next empty slot on the same track.
  • Copy to arrangement: right-click a slot that references a clip and choose Copy to arrangement, or drag the slot onto the Workspace timeline. This creates a new arrangement clip at the current transport position with the same content as the referenced clip.
  • Assign clip to session slot: in the workspace, select a session slot on the target track (in Session view), then right-click an arrangement clip on that track and choose Assign to session slot. The selected slot will reference that clip.
  • Import arrangement to session: available from the View menu; creates a scene and fills each track’s slots with references to its arrangement clips.
  • Record session to arrangement: click the Rec to Arr button in the top-left of the session grid. This arms tracks that have session slots, starts playback if needed, enables recording, and writes new arrangement clips through the existing record path.
  • Record into slot: right-click a slot and choose Record into slot. This arms the track, starts playback and recording if needed, and assigns the newly recorded clip to that slot when the clip is created.
  • Scene options: right-click a scene header to rename it, set its color, set a per-scene tempo, or change its launch quantization.
  • Track strip: the left column shows each track’s name plus compact mute, solo, arm, volume, and pan controls.

Templates

Session templates live under:

~/.config/maolan/session_templates/<name>/

Each session template contains a session.json (templates are not branch-aware) plus the same supporting subdirectories used by a normal session. Session templates keep:

  • track structure
  • routing
  • plugin graphs and plugin state
  • session metadata
  • export settings

Session templates intentionally do not keep:

  • audio clips
  • MIDI clips
  • frozen render state or frozen backups

Track templates live under:

~/.config/maolan/track_templates/<name>/

Each track template stores track.json plus a plugins/ directory. Track templates keep:

  • one track’s settings
  • that track’s plugin graph and plugin state
  • connections involving that track

Folder track templates are stored in the same location. A folder template’s track.json also contains a children array with the saved subtree (each child has the same track/graph/children shape). Folder templates keep:

  • the folder track’s settings
  • the folder’s plugin graph and plugin state
  • child-to-folder-plugin connectable connections
  • disabled child-to-folder-output feeds
  • internal connections between folder members
  • the full child track subtree, recursively

Track and folder templates intentionally do not keep:

  • audio clips
  • MIDI clips
  • connections to tracks outside the saved subtree

Cross-format restore behavior

Mixed Unix graphs containing LV2 and CLAP plugins are restored in saved order. VST3 state is preserved through the current host restore path as well, so sessions and templates retain routing intent instead of reconstructing a simplified chain.

Modulators

The Modulators pane (View → Modulators or M) shows the session’s LFO-style modulators.

  • Press + to add a modulator.
  • Each modulator has a name, enable toggle, shape, rate mode, rate value, and phase offset.
  • Rate can be set in Hz or in musical divisions (bar, half, beat, eighth, … sixty-fourth).
  • While a modulator is selected, mixer faders/pans and automation-lane headers show a target overlay.
  • Click the overlay (or use the track context menu) to open the Assign modulator dialog.
  • The dialog asks for a min and max value; the modulator output is scaled to that range.
  • Targets include track Volume/Balance, visible automation lanes (plugin parameters, MIDI CC), and master output Volume/Balance.
  • Existing assignments can be removed from the same dialog.

Modulator assignments are saved in the session and restored on load.

Step Recording

Step recording is a MIDI input mode in the piano roll for entering notes one step at a time.

  • Open a MIDI clip in the piano roll (double-click a MIDI clip).
  • Toggle step recording from the toolbar (Step button), visible only while the MIDI editor is active.
  • When enabled, the editor shows a step cursor at the current insert position.
  • Played MIDI notes are inserted at the step cursor with length equal to the current MIDI snap interval, and the cursor advances automatically.
  • NoSnap / Clips snap modes fall back to a sixteenth-note step length.

Fold Mixer Strips

Folder tracks render in the mixer as collapsible strips.

  • Folder mixer strips have a ▼ / ▶ toggle in their header; click it to expand or collapse the child tracks.
  • When expanded, child tracks are nested to the right of the folder strip.
  • When collapsed, only the folder strip is shown.
  • Folder strips omit the record-arm button because folders cannot be armed.
  • Double-click a folder strip to open its connections graph.

Autosave and Recovery

  • Autosave snapshots are generated every 15 seconds.
  • Snapshots are stored in <session>/.maolan_autosave/snapshots/<timestamp>/.
  • A snapshot is considered valid when it contains a <branch>.json file.
  • Recovery prefers newer snapshots and sorts them newest-first.
  • On startup or open, Maolan can detect when the newest autosave snapshot is newer than the live <branch>.json.
  • Recovery preview currently summarizes track, audio-clip, and MIDI-clip count deltas between the live session and the selected snapshot.

Recovering an autosave snapshot loads that snapshot as the current session state and marks the session as having unsaved changes.

Recovery boundaries

  • Newest-first sorting: Snapshot selection prefers the most recent valid entry rather than trying to merge newer pieces from multiple points in time.
  • Unsaved state after restore: Restore is a recovery load, not a silent replacement of the live project file, so the session remains dirty until saved.
  • Undo / redo note: Graph connection edits and plugin load or unload actions are covered by undo and redo. Low-level state-restore mechanics are internal replay behavior, not user-facing history items.

Loop, punch-range, and record-enable toggles are history-recorded. Tempo and time-signature edits, modulator changes, track hierarchy changes, clip plugin graph changes, automation lane edits, and pitch-correction edits are history-recorded. Track automation level, balance, and mute updates are runtime path edits and are excluded from history. Transport/query/report actions are intentionally kept out of history. High-frequency automation playback adjustments are also excluded to avoid history noise. MIDI learn arm actions are excluded; actual mapping changes remain history-recorded. Plugin discovery and host-state introspection actions are not recorded in history.

Diagnostics

The UI exposes:

  • Session Diagnostics
  • MIDI Mappings Report
  • Export Diagnostics Bundle

Exported diagnostics bundles are written to:

  • <session>/maolan_diagnostics_<unix-seconds>/ when a session is open
  • /tmp/maolan_diagnostics_<unix-seconds>/ otherwise

Current bundle contents:

  • session_diagnostics.txt
  • midi_mappings.txt
  • ui_summary.json

Export Behavior

  • Mixdown export renders the selected hardware output ports.
  • Stem export writes one file per eligible selected track into <base>_stems/.
  • Multiple output formats can be written in one export run.
  • MP3 export supports only mono or stereo output.
  • Normalization, master-limiter, and dither settings are persisted in the session file.
  • Dither is applied when exporting to integer PCM formats (WAV/FLAC at 16/24/32-bit). It is skipped for 32-bit float and for lossy formats (MP3/OGG).

HeartMuLa Generation Operations

The current HeartMuLa generation path uses the maolan-generate crate/binary.

  • The GUI launches generate through the local maolan-generate binary and exchanges requests over a socketpair IPC path.
  • Prompt generation runs as a dedicated HeartMuLa token-generation subprocess, then decode runs in-process with HeartCodec.
  • When --model-dir <path> is not provided, the generate path resolves models from the Hugging Face cache via hf-hub.
  • The expected Hugging Face Burn repos are:
    • maolandaw/HeartMuLa-happy-new-year-burn
    • maolandaw/HeartMuLa-RL-oss-3B-20260123
    • maolandaw/HeartCodec-oss-20260123-burn
  • The generate path currently expects these repo file layouts:
    • HeartMuLa repo: heartmula.bpk, tokenizer.json, gen_config.json
    • HeartCodec repo: heartcodec.bpk
  • The current CLI supports --model <happy-new-year|RL>.
  • The current CLI uses --length <int> in milliseconds for output duration.
  • --decode-only requires --frames-json <path>.
  • --decode-threads <int> can be used to control decode-only CPU worker count.
  • --model-dir <path> can be used to bypass Hugging Face cache resolution and point at a local export directly.

Media Consolidation and File References

Maolan can collect external media files into the session directory and update plugin file references to keep sessions portable.

  • File → Consolidate copies imported audio/MIDI files and any CLAP/LV2 plugin file references into the session’s data/ directory.
  • Consolidation updates plugin file references to absolute paths immediately, and saved plugin state is rewritten to relative data/ paths on save.
  • File → Delete unused files scans audio/, midi/, peaks/, and pitch/ and removes files not referenced by the current session or any non-hidden branch JSON. Unused clips (deleted from tracks but kept in the Clips pane’s Unused section) are permanently removed first when no session slot of the current branch references them and no other branch file references their media; clips still used in the live or edit view of any session file stay in the Unused section.
  • Consolidation makes it safer to move or share a session directory.

Pitch Correction Caching and Rendering

  • Opening pitch correction for an audio clip requires a saved/opened session.
  • Analysis results are cached per session under pitch/ and reused when the source file modification time still matches.
  • Cached analysis is keyed by source file, source offset, and source length, so clip corrections can target either the whole clip or a saved source window.
  • Pressing Apply stores the current correction points and render settings on the clip without destructively rewriting the source audio file.
  • Live transport playback applies saved pitch correction in real time.
  • Freeze preparation renders pitch-corrected clips offline first so frozen audio matches the corrected result.

Clip Groups and Per-Clip FX

  • Grouping replaces the selected top-level clips with one parent clip whose grouped_clips store child timing relative to the group start.
  • Grouping is only available for selections of two or more clips from the same track and the same clip kind.
  • Child fades are cleared during grouping; the group clip owns the audible fades after grouping.
  • Ungroup restores children at their absolute timeline positions and preserves nested groups.
  • Grouped clips cannot be split directly.
  • Audio clips can also store an independent plugin graph in plugin_graph_json.
  • On supported Unix builds, opening clip plugins seeds a default passthrough graph when a clip has no saved graph yet.
  • In the current audio engine path, grouped audio children are summed, the group fade is applied, and the group clip plugin graph runs after that sum; leaf audio clips can also run their own plugin graphs.

Recent Sessions

Recent sessions are stored in config.toml via recent_session_paths.

  • paths are normalized before display
  • duplicates are removed
  • invalid paths are dropped
  • the list is capped to the app’s configured recent-session limit

Plugin Routing and Sidechains

Last updated: 2026-07-09

Overview

Maolan uses a per-track plugin graph instead of a fixed insert-only chain. A track can contain:

  • Track audio inputs and outputs
  • Track MIDI inputs and outputs
  • LV2 plugin nodes on Unix
  • CLAP plugin nodes
  • VST3 plugin nodes

Connections are explicit. Audio and MIDI routing are managed separately.

Audio clips on supported Unix builds can also carry their own per-clip plugin graph. That graph is separate from the parent track graph and is stored with the clip in session data.

Folder tracks also have their own plugin graph. Child tracks route into the folder graph, and child outputs can also be connected directly to folder plugins or to the folder output.

Default Behavior

  • A new track starts with default passthrough routing from track inputs to track outputs.
  • MIDI passthrough is also created for the first input/output path.
  • Loading plugins does not remove existing routing automatically; the graph determines the signal path.
  • Opening an audio clip plugin graph seeds a default passthrough clip graph if the clip does not already have one.

Audio Ports

Plugin audio ports are shown as:

  • Main audio ports
  • Extra / auxiliary / sidechain ports

Extra audio ports, including sidechains, are rendered in orange so they are visually distinct from main audio ports.

This matters for plugins such as:

  • compressors with dedicated sidechain inputs
  • plugins exposing auxiliary sends/returns
  • plugins with additional analysis or detector inputs

MIDI Ports

MIDI connections are explicit in the graph as well.

  • A plugin with MIDI input must be connected to receive MIDI.
  • A plugin with MIDI output must be connected to a downstream node or track output for events to continue.
  • VST3, CLAP, and LV2 MIDI paths are handled per plugin format and per track graph node.

Session and Template Restore

Plugin graph state is part of save/restore workflows.

  • Session save/load restores plugin graph topology.
  • Session save/load also restores per-audio-clip plugin graphs.
  • Track templates restore plugin order, plugin state, and graph connections.
  • Mixed Unix graphs containing LV2 and CLAP plugins are restored in saved order.
  • VST3 state is also preserved through the plugin restore paths used by the current host integration.

Per-Clip FX Notes

  • Per-clip plugin graphs are currently audio-only.
  • They are opened by double-clicking an audio clip in the timeline.
  • A grouped audio clip can have its own plugin graph, and child audio clips can also keep their own plugin graphs.
  • In the current render path, child clips are rendered first, then group-level fades are applied, then the group plugin graph is processed.

Practical Workflow

Typical sidechain setup:

  1. Open the track plugin graph.
  2. Load the destination plugin, for example a compressor.
  3. Identify the orange sidechain input port on that plugin.
  4. Connect the source track or upstream plugin output to that sidechain port.
  5. Keep the main audio path connected separately to the plugin’s main input.

Typical serial insert setup:

  1. Disconnect the default track-input to track-output passthrough if needed.
  2. Connect Track Input -> Plugin A -> Plugin B -> Track Output.

Typical MIDI instrument/effect setup:

  1. Connect MIDI source to the instrument/effect MIDI input.
  2. Connect audio output of the instrument/effect to the next plugin or track output.
  3. If the plugin emits MIDI, connect its MIDI output explicitly.

Notes and Boundaries

  • Plugin compatibility still depends on the host implementation and the plugin itself.
  • Some plugins expose unusual bus layouts; the graph is the source of truth for what is connected.
  • Undo/redo covers graph connection edits and plugin load/unload actions, but low-level state-restore actions are internal replay mechanisms rather than user-facing history items.

Maolan Shortcuts and Gestures

Last updated: 2026-07-09

Keyboard Shortcuts

Global / Session

  • Ctrl+N: New session
  • Ctrl+O: Open session
  • Ctrl+S: Save session
  • Ctrl+Shift+S: Save session as
  • Ctrl+I: Import files
  • Ctrl+E: Open export dialog
  • Ctrl+T: Add track
  • Ctrl+A: Select all (in pitch-correction view: selects all segments)
  • Ctrl+R: Toggle session record arm
  • Ctrl+L: Send transport panic / MIDI panic
  • Ctrl+Z: Undo
  • Ctrl+Shift+Z: Redo
  • Ctrl+Y: Redo
  • Delete or Backspace: Remove selected item(s)
  • Escape: Cancel or clear the current context-dependent interaction
  • S: Toggle the Shortcuts pane
  • M: Toggle the Modulators pane
  • C: Toggle the Clips pane
  • X: Toggle the cut indicator (a vertical guide line showing where a cut would land; only visible in workspace view)

Transport

  • Space: Toggle play/stop
  • Shift+Space: Pause (arrangement); stop all session clips when Session view is focused
  • Home: Rewind to start
  • End: Rewind to end

Session View

  • Tab: Toggle between Workspace and Session view
  • / / / : Navigate selected clip slot
  • Return: Launch or stop the selected slot
  • Shift+Space: Stop all session clips
  • Rec to Arr button: Start recording playing session clips into the arrangement

Piano Tools

  • Q: Quantize selected notes
  • H: Humanize selected notes
  • G: Groove selected notes

Mouse Actions and Gestures

Workspace / Track List

  • Left click track: Select track
  • Ctrl+Left click track: Add track to the current selection
  • Double click track: Open the track plugin/routing graph
  • Right click track: Open track context menu
    • Track actions such as automation lanes, rename, sends/returns, MIDI learn, freeze/flatten, and template save depending on track state
  • Drag track (grab track body): Reorder track
  • Drag bottom track edge: Resize track height

Timeline Clips

  • Left click clip: Select clip
  • Left click empty editor: Deselect clips
  • Left drag clip: Drag/move clip (or group if multi-selected)
  • Ctrl + drag clip: Copy clip while dragging
  • Drag clip left/right edge: Resize clip bounds
  • Shift + drag clip left/right edge: Stretch audio clip with the built-in timestretch renderer on drop
  • Snapping is applied during drag-and-drop based on the current snap mode; the “Clips” snap mode enables snapping to other clip start/end positions
  • Drag clip fade handles: Resize fade-in/fade-out
  • Middle click clip: Split clip at current cursor/snap position
  • Double click MIDI clip: Open MIDI piano roll
  • Double click audio clip: Open per-clip plugin graph on supported Unix builds
  • Right click clip: Open clip context menu
    • Clip actions such as group/ungroup, rename, take-lane controls, mute/unmute, pitch correction, fade toggle, and audio stretch actions for audio clips

Track Header Markers

  • Right click empty marker/header area: Open the create-marker dialog at the snapped timeline position
  • Left drag marker: Move marker horizontally; snapping is applied on drop (supports “Clips” snap mode)
  • Right click marker: Rename marker
  • Middle click marker: Delete marker

Selection Gestures

  • Left drag on empty editor: Marquee clip selection rectangle
  • Right drag on MIDI lane: Create empty MIDI clip

Automation Lanes

  • Right drag empty area: Draw a straight automation ramp between the press and release points (same interaction as the MIDI controller lane). A click without movement inserts a single point.
  • Right click point: Delete automation point

Ruler (Top Timeline)

  • Left click: Move transport playhead
  • Left drag: Set loop range (snap-aware, supports “Clips” snap mode)
  • Right drag inside loop range: Move the entire loop range
  • Middle drag loop edge: Adjust loop start or end point
  • Right click: Clear loop range

Zoom Controls

  • Main editor zoom: Bottom-right horizontal slider
  • Piano roll horizontal zoom: Bottom slider in the MIDI editor
  • Piano roll vertical zoom: Right-side vertical slider in the MIDI editor

Tempo / Time Signature Lane

  • Left click marker: Select marker
  • Shift+Left click marker: Add/remove marker from selection
  • Left drag selected marker(s): Move marker(s) in time (supports “Clips” snap mode)
  • Left click empty timing lane: Clear timing selection and move the playhead
  • Left drag empty timing lane: Clear timing selection and set punch range (supports “Clips” snap mode)
  • Right click marker: Open marker context menu
    • Duplicate
    • Reset to previous
    • Delete
  • Right click empty timing lane: Clear timing selection and clear punch range
  • Right drag empty timing lane: Clear timing selection and set punch range (supports “Clips” snap mode)
  • Middle click on tempo lane: Add tempo point (supports “Clips” snap mode)
  • Middle click on time-signature lane: Add time-signature point (supports “Clips” snap mode)
  • Middle drag an existing punch-range edge: Adjust punch start or end (supports “Clips” snap mode)
  • Mouse wheel over left control zone on tempo row: Adjust tempo
  • Mouse wheel over left control zone on time-signature row, left half: Adjust numerator
  • Mouse wheel over left control zone on time-signature row, right half: Adjust denominator

Piano Roll (Mouse)

  • Click/drag notes: Select and move notes
  • Drag note edge: Resize note start/end
  • Left drag empty area: Box-select notes
  • Right drag empty area: Create notes
  • Middle click note: Delete note
  • Mouse wheel over note: Adjust note velocity
  • Controller lanes: Left drag adjusts a point/value, middle click/drag erases, right drag draws
  • Mouse wheel over controller event: Adjust controller value
  • SysEx lane: Left drag moves SysEx event, double click opens SysEx editor

Pitch Correction

  • Right click audio clip -> Pitch Correction: Open the pitch-correction editor when transport is stopped
  • Left click pitch segment: Select one segment
  • Shift+Left click pitch segment: Add/remove a segment from the selection
  • Left drag selected pitch segment(s): Retarget one or many selected segments vertically
  • Left drag empty area: Box-select pitch segments
  • Shift+Left drag empty area: Add box-selected segments to the current selection
  • Double click pitch segment: Snap the clicked segment, or the current selected group, to the nearest semitone
  • Ctrl+A in pitch-correction view: Select all segments
  • Ctrl+Z / Ctrl+Shift+Z / Ctrl+Y in pitch-correction view: Undo/redo local pitch-segment edits

Plugin Graph

  • Drag plugin node: Move plugin node in graph
  • Drag from port to port: Create audio or MIDI connection
  • Select connection + delete: Remove selected graph connection
  • Select plugin + delete: Remove selected plugin instance

Shortcuts Pane

The in-app Shortcuts pane can be shown or hidden with S or via View → Shortcuts. It displays context-sensitive shortcuts for the active view (workspace, piano roll, pitch correction, or plugin graph) and highlights the relevant entry when hovering a widget that has a shortcut hint.

Clips Pane

The in-app Clips pane can be shown or hidden with C or via View → Clips. It lists every audio and MIDI clip in the session, grouped by track. Clips belonging to the currently selected track(s) are highlighted in the pane; this highlighting is only in the Clips pane and does not change the main editor or timeline.

Deleting a clip from a track does not discard it: the clip moves to the “Unused” section at the bottom of the Clips pane and stays part of the session. A clip counts as unused only when it is used in neither the edit view (no track holds it) nor the live view (no session slot references it) — a clip removed from the timeline but still assigned to a session slot keeps playing in the live view and does not appear in the Unused section until the slot is cleared. Clips in the pane can be dragged onto a track in the editor (placed at the drop position, using the current snap mode): dragging a track’s clip copies it with a fresh id, while dragging an unused clip moves it out of the Unused section. Pane clips can also be dragged directly onto a session slot in the live view to assign them to that slot. Re-adding an unused clip to a track via undo also removes it from the Unused section. File → Delete unused files permanently removes an unused clip — from the pane and from the session — and deletes its media, but only when no session slot of the current branch references the clip and no other branch/session file still references its media.

maolan-cli

Maolan also ships a maolan-cli binary that can play, pause, stop, send panic, and export the current session.

Notes

  • Current keyboard handling is Ctrl-based in code paths (including on macOS builds).
  • Some actions are context-dependent (current view/tool/selection state).
  • The Q / H / G piano shortcuts act on the current piano-roll note selection.
  • In pitch-correction view, undo/redo applies to the local correction editor instead of global engine history until you leave the view or press Apply.
  • Audio clip stretching is rendered in-process with the timestretch library.
  • The main editor zoom is geometric rather than linear, so equal slider movement produces equal zoom-ratio changes.
  • Group is only enabled when the current selection contains two or more non-group clips from the same track and clip type.
  • Split is blocked for grouped clips; ungroup first.
  • Per-clip plugin graphs are audio-only and are currently built for Unix non-macOS code paths.

Maolan OSC

Maolan supports an OSC control surface for transport, track management, routing, plugins, automation, clip editing, MIDI editing, MIDI learn, audio/MIDI devices, offline bounce, and state queries.

OSC is disabled by default.

Enabling OSC

Enable OSC from Preferences in the GUI:

  1. Open Preferences.
  2. Turn on Enable OSC.
  3. Save preferences.

Once enabled, Maolan starts an OSC listener thread in the engine.

The preference is stored in:

~/.config/maolan/config.toml

OSC Listener

The engine listens on:

0.0.0.0:9000

There is no /maolan prefix on any OSC address.

Command Addresses

Arguments use OSC type tags:

  • i — integer
  • f — float
  • s — string
  • T / F — true / false (also accepted as i 0/1)

Transport

  • /transport/play
  • /transport/stop
  • /transport/pause
  • /transport/start
  • /transport/end
  • /transport/position i — set transport position in samples
  • /transport/position_at i i — set position after N frames
  • /transport/session_play
  • /transport/record i — enable (1) or disable (0) recording
  • /transport/loop_enable i
  • /transport/loop_range ii — start, end in samples
  • /transport/loop_range/clear — clear the loop range
  • /transport/punch_enable i
  • /transport/punch_range ii — start, end in samples
  • /transport/punch_range/clear — clear the punch range
  • /transport/metronome i
  • /transport/clip_playback i
  • /transport/session_clip_playback i
  • /transport/panic
  • /transport/tempo f — set tempo in BPM
  • /transport/time_signature ii — numerator, denominator
  • /transport/tempo_map s — JSON tempo/time-signature map
  • /step_recording i — enable (1) or disable (0) step recording

Compatibility aliases are still accepted:

  • /transport/jump_to_start/transport/start
  • /transport/jump_to_end/transport/end
  • /transport/start_of_session/transport/start
  • /transport/end_of_session/transport/end

Tempo map JSON format:

{
  "tempo_points": [
    {"sample": 0, "bpm": 120.0}
  ],
  "time_signature_points": [
    {"sample": 0, "numerator": 4, "denominator": 4}
  ]
}

Session

  • /session/launch s i — launch clip on track/scene
  • /session/stop s i — stop clip on track/scene
  • /session/scene i — launch every clip in the given scene
  • /session/stop_scene i — stop every clip in the given scene
  • /session/stopall — stop all currently playing session clips
  • /session/path s — set session path

History is intentionally not exposed over OSC.

Track Management

  • /track/add s i i i i i — name, audio_ins, midi_ins, audio_outs, midi_outs, folder
  • /track/remove s
  • /track/rename s s
  • /track/set_folder s i
  • /track/toggle_folder s
  • /track/set_parent s s — empty parent string removes the parent
  • /track/add_audio_input s
  • /track/remove_audio_input s
  • /track/add_audio_output s
  • /track/remove_audio_output s

Track Mixing / State

  • /track/level s f
  • /track/balance s f
  • /track/automation_level s f
  • /track/automation_balance s f
  • /track/midi_cc s i i i — track_name, channel, cc, value
  • /track/mute s i
  • /track/solo s i
  • /track/arm s i
  • /track/phase s i
  • /track/master s i
  • /track/color s f f f [f] — RGBA (alpha defaults to 1.0)
  • /track/color/clear s — clear the track color
  • /track/frozen s i
  • /track/midi_lane_channel s i i — channel -1 clears the assignment
  • /track/session_slot s i s
  • /track/session_slot_play_enabled s i i
  • /track/toggle_input_monitor s i
  • /track/toggle_disk_monitor s i
  • /track/toggle_midi_input_monitor s i
  • /track/toggle_midi_disk_monitor s i
  • /track/clear_default_passthrough s
  • /track/clear_plugins s
  • /track/connect_audio s s i s i
  • /track/disconnect_audio s s i s i
  • /track/connect_midi s s i s i
  • /track/disconnect_midi s s i s i

Connectable node strings: "track_input", "track_output", "child:<name>", "clap_<id>", "vst3_<id>", "lv2_<id>".

Routing

  • /connect s i s i s — from_track, from_port, to_track, to_port, kind
  • /disconnect s i s i s

kind is "audio" or "midi".

Clips

  • /clip/add s s i i i i i i i i s [s] [s] — track, name, start, length, offset, input_channel, muted, fade_enabled, fade_in, fade_out, kind, optional source_name, optional preview_name
  • /clip/remove s s s — track, kind, comma-separated indices
  • /clip/move s s i s i i i — kind, from_track, from_index, to_track, to_offset, to_channel, copy
  • /clip/fade s i s i i i — track, clip_index, kind, fade_enabled, fade_in_samples, fade_out_samples
  • /clip/bounds s i s i i i — track, clip_index, kind, start, length, offset
  • /clip/mute s i s i
  • /clip/rename s i s s
  • /clip/source_name s i s s
  • /clip/plugin_graph_json s i s — empty JSON string clears the graph
  • /clip/pitch_correction s i s — JSON pitch-correction data or empty string
  • /clip_group/add s s s s — track, kind, audio_clip JSON, midi_clip JSON

Pitch-correction JSON format:

{
  "preview_name": "preview.wav",
  "source_name": "source.wav",
  "source_offset": 0,
  "source_length": 44100,
  "frame_likeness": 0.5,
  "inertia_ms": 50,
  "formant_compensation": false,
  "points": [
    {
      "start_sample": 0,
      "length_samples": 1000,
      "detected_midi_pitch": 60.0,
      "target_midi_pitch": 61.0,
      "clarity": 0.9
    }
  ]
}

MIDI Editing

All MIDI editing commands take a JSON string as the last argument.

  • /midi/insert_notes s i s
  • /midi/delete_notes s i s
  • /midi/modify_notes s i s
  • /midi/insert_controllers s i s
  • /midi/delete_controllers s i s
  • /midi/modify_controllers s i s
  • /midi/sysex s i s
  • /midi/step_record s i i i — device, channel, pitch, velocity

Insert-notes JSON format:

[
  {"index": 0, "start_sample": 0, "length_samples": 1000,
   "pitch": 60, "velocity": 100, "channel": 0}
]

Delete-notes JSON format:

{
  "indices": [0, 1],
  "deleted": [
    {"index": 0, "start_sample": 0, "length_samples": 1000,
     "pitch": 60, "velocity": 100, "channel": 0}
  ]
}

Modify-notes JSON format:

{
  "indices": [0, 1],
  "new": [{"start_sample": 0, "length_samples": 1000, "pitch": 60, ...}],
  "old": [{"start_sample": 0, "length_samples": 1000, "pitch": 59, ...}]
}

Controller JSON objects use sample, controller, value, and channel. SysEx JSON format:

[{"sample": 0, "data": [240, 1, 2, 247]}]

Plugins

  • /plugin/load s s s — track_name, format ("clap", "vst3", "lv2"), plugin ID
  • /plugin/unload s s s
  • /plugin/unload_instance s s i
  • /plugin/bypass s s i i — track_name, format, instance_id, bypassed
  • /plugin/show_gui s s i
  • /plugin/snapshot_state s s i
  • /plugin/restore_state s s i s — JSON state ({"bytes":[...]} for CLAP, {"plugin_id":"...","component_state":[...],"controller_state":[...]} for VST3)
  • /plugin/set_resource_dir s s i s
  • /plugin/update_file_reference s s i i s — track_name, format, instance_id, file_index, path
  • /plugin/connect_audio s s i s i
  • /plugin/disconnect_audio s s i s i
  • /plugin/connect_midi s s i s i
  • /plugin/disconnect_midi s s i s i
  • /plugin/set_param s s i i f
  • /clip_plugin/set_param s s i i i f
  • /clip_plugin/snapshot_state s s i i
  • /clip_plugin/restore_state s s i i s
  • /clip_plugin/set_resource_dir s s i i s
  • /clip_plugin/update_file_reference s s i i i s

Plugin graph node strings:

  • "track_input"
  • "track_output"
  • "clap_<instance_id>"
  • "vst3_<instance_id>"
  • "lv2_<instance_id>"

Automation

Automation targets supported in OSC:

  • "volume"
  • "balance"
  • "midi_cc_<channel>_<cc>" — channel is 1–16

Addresses:

  • /automation/mode s s — track_name, mode ("read", "touch", "latch", "write")
  • /automation/toggle_lane s s
  • /automation/insert_point s s i f — track_name, target, sample, value
  • /automation/delete_point s s i — track_name, target, sample

MIDI Learn

Track targets: volume, balance, mute, solo, arm, input_monitor, disk_monitor.

Global targets: play_pause, stop, record_toggle.

Session target strings:

  • slot:<track>:<scene>
  • scene:<scene>
  • stop_track:<track>
  • stop_all

Binding JSON (empty string clears):

{"device": "X-Touch", "channel": 1, "cc": 7}

Addresses:

  • /midi_learn/arm_track s s
  • /midi_learn/arm_global s
  • /midi_learn/arm_session s
  • /midi_learn/bind_track s s s
  • /midi_learn/bind_global s s
  • /midi_learn/bind_session s s
  • /midi_learn/clear

Modulators / Devices

  • /modulators s — JSON array of modulators
  • /device/audio_open s — JSON audio-device configuration
  • /device/midi_in_open s
  • /device/midi_out_open s
  • /device/jack/add_audio_in
  • /device/jack/remove_audio_in i
  • /device/jack/add_audio_out
  • /device/jack/remove_audio_out i

Audio-device JSON format:

{
  "device": "hw:0",
  "input_device": "hw:0",
  "sample_rate_hz": 48000,
  "bits": 32,
  "exclusive": false,
  "period_frames": 256,
  "nperiods": 2,
  "sync_mode": false,
  "actual_period_frames": 256,
  "input_channels": 2,
  "output_channels": 2,
  "bytes_per_frame": 8
}

Offline Bounce

  • /bounce/start s s i i s i — track, output_path, start_sample, length_samples, automation_lanes JSON, apply_fader
  • /bounce/cancel s
  • /bounce/cancel_all

Piano Key

  • /piano_key s i i i — track_name, note, velocity, on

Query Addresses

Queries return replies to the sender.

  • /query/tracks/response/tracks s...
  • /query/transport/response/transport i i f i i (sample, playing, tempo, time_sig_num, time_sig_denom)
  • /query/meters/response/meters ...
  • /query/plugins s/response/plugins s i (i s s s i)* (track_name, plugin_count, instance_id, format, uri, name, bypassed)
  • /query/plugin_parameters s s i i/response/plugin_parameters s i s s (track_name, instance_id, format, parameters_json)
  • /query/clip_plugin_parameters s s i i i → clip plugin parameters reply
  • /query/clap_plugins/response/clap_plugins s...
  • /query/clap_plugins_with_capabilities → list with I/O capabilities
  • /query/vst3_plugins/response/vst3_plugins s...
  • /query/lv2_plugins/response/lv2_plugins s...
  • /query/clap_note_names s/response/clap_note_names s...
  • /query/lv2_midnam s/response/lv2_midnam s ... (LV2 midnam MIDI note names; Unix only)
  • /query/vst3_graph s/response/vst3_graph s...
  • /query/diagnostics/response/diagnostics s...
  • /query/midi_learn_report/response/midi_learn_report s...

Plugin-list replies contain strings in the form id|name for CLAP and VST3, uri|name for LV2.

Errors are reported as:

  • /error s

maolan-osc Helper

The repository includes a command-line helper:

maolan-osc

Global Options

maolan-osc --target 127.0.0.1:9000 play
maolan-osc --host 192.168.1.10 --port 9000 stop
maolan-osc --file commands.txt

--file <path> reads commands from a file, one per line, using the same syntax as the command line. Blank lines and lines starting with # are ignored, and single or double quotes group arguments that contain whitespace (track names, JSON payloads). The whole file is parsed first and every error is reported with its line number; packets are sent only when the file parses without errors.

Example command file:

# set up a mix
track level "Drums" -6.0
track mute "Drums" 1
tempo 128.5

A ready-made example file with five commands is available at maolan/docs/commands.txt in the repository.

Examples

cargo run --bin maolan-osc -- play
cargo run --bin maolan-osc -- stop
cargo run --bin maolan-osc -- pause
cargo run --bin maolan-osc -- start
cargo run --bin maolan-osc -- end

cargo run --bin maolan-osc -- position 44100
cargo run --bin maolan-osc -- tempo 128.5
cargo run --bin maolan-osc -- record 1

cargo run --bin maolan-osc -- track add "Vocals" 2 0 2 0
cargo run --bin maolan-osc -- track remove "Vocals"
cargo run --bin maolan-osc -- track rename "Vocals" "Lead Vocals"
cargo run --bin maolan-osc -- track folder "Buses" 1
cargo run --bin maolan-osc -- track parent "Kick" "Drums"

cargo run --bin maolan-osc -- track level "Drums" -6.0
cargo run --bin maolan-osc -- track mute "Drums" 1
cargo run --bin maolan-osc -- track solo "Drums" 1
cargo run --bin maolan-osc -- track arm "Vocals" 1

cargo run --bin maolan-osc -- connect "Kick" 0 "Drums" 0 audio
cargo run --bin maolan-osc -- disconnect "Kick" 0 "Drums" 0 audio

cargo run --bin maolan-osc -- plugin load "Drums" clap "rs.maolan.widener"
cargo run --bin maolan-osc -- plugin bypass "Drums" clap 0 1
cargo run --bin maolan-osc -- plugin connect_audio "Drums" track_input 0 clap_0 0
cargo run --bin maolan-osc -- plugin set_param "Drums" clap 0 0 0.75

cargo run --bin maolan-osc -- track connect_audio "Drums" child:"Sub" 0 track_output 0

cargo run --bin maolan-osc -- clip add "Vocals" "Take 1" 0 44100 0 0 0 1 100 100 audio

cargo run --bin maolan-osc -- midi insert_notes "Piano" 0 '[{"index":0,"start_sample":0,"length_samples":1000,"pitch":60,"velocity":100,"channel":0}]'

cargo run --bin maolan-osc -- automation mode "Drums" touch
cargo run --bin maolan-osc -- automation point "Drums" midi_cc_1_7 44100 64.0

cargo run --bin maolan-osc -- midi_learn bind_track "Drums" volume '{"device":"X-Touch","channel":1,"cc":7}'

cargo run --bin maolan-osc -- query tracks
cargo run --bin maolan-osc -- query transport
cargo run --bin maolan-osc -- query meters
cargo run --bin maolan-osc -- query plugins "Drums"
cargo run --bin maolan-osc -- query plugin_parameters "Drums" clap 0
cargo run --bin maolan-osc -- query clap_plugins
cargo run --bin maolan-osc -- query clap_plugins_with_capabilities
cargo run --bin maolan-osc -- query diagnostics

cargo run --bin maolan-osc -- session stop_scene 2
cargo run --bin maolan-osc -- track automation_level "Drums" -6.0
cargo run --bin maolan-osc -- track midi_cc "Drums" 1 7 64
cargo run --bin maolan-osc -- step_recording 1

cargo run --bin maolan-osc -- plugin show_gui "Drums" clap 0
cargo run --bin maolan-osc -- plugin snapshot_state "Drums" clap 0
cargo run --bin maolan-osc -- plugin restore_state "Drums" clap 0 '{"bytes":[1,2,3]}'
cargo run --bin maolan-osc -- plugin update_file_reference "Drums" clap 0 0 "/tmp/sample.wav"

cargo run --bin maolan-osc -- clip_plugin snapshot_state "Drums" clap 0 0

Run maolan-osc --help for the full command list.

Notes

  • OSC only starts after it is enabled in preferences and the setting has been saved.
  • If OSC is disabled, maolan-osc can still send packets, but the engine will not be listening for them.
  • Query replies are sent to the source address of the request.
  • Complex structured data (clip data, MIDI notes, controllers, tempo maps, modulators, audio-device settings, automation lanes) is sent as JSON strings because the OSC implementation uses flat typed arguments rather than bundles.

Maolan Plugins

The complete Maolan in-house plugin collection. Built in Rust as CLAP plugins with Iced-based GUIs in the TokyoNight theme.

  • 18 exported variants
  • 13 distinct products
  • Iced TokyoNight GUI
  • BSD-2 license

Dynamics

Compressors, limiters, and de-essers for controlling dynamics and taming peaks.

Compressor

Plugin ID: rs.maolan.compressor

4-band multiband compressor with LR4 crossovers. Peak/RMS sidechain, downward/upward/boosting modes, lookahead, sidechain boost, and classic/modern topology. Based on LSP.

Limiter

Plugin ID: rs.maolan.limiter

Adaptive clipper/limiter with Vintage and Modern variants. Multiple limiting modes from subtle attenuation to aggressive clipping. Stereo I/O.

DeEsser

Plugin ID: rs.maolan.deesser

Sibilance reduction processor. Detects ess sounds via slew-rate patterns across a configurable window. IIR smoothing, dynamic ratio reduction, and monitor mode. Stereo I/O.

EQ

Precise tone shaping with 32 bands in both graphic and parametric flavors.

Parametric EQ

Plugin ID: rs.maolan.equalizer

32-band parametric equalizer using peaking biquad filters. Each band has independent Frequency, Gain, Q, Type, Slope, and Dynamics controls. Input and output gain with global bypass. Mono or stereo I/O depending on host channel count.

Time & Space

Delays and reverbs for depth, dimension, and atmosphere.

Delay

Plugin ID: rs.maolan.delay

Delay with millisecond or tempo-synced note divisions. Circular buffers with linear interpolation and smooth delay-time chasing. Reads host BPM from CLAP transport.

Reverb

Plugin ID: rs.maolan.reverb

Stereo reverb built from three allpass-like delay blocks with cross-feedback, vibrato predelay, and input/output lowpass filters. Based on Airwindows Reverb.

Stereo

Stereo width processors and imagers for spatial control.

Stereo

Plugin ID: rs.maolan.stereo

Stereo width processor. Mid/side processing with density controls and delay-based focus. Stereo I/O. Best suited for mastering.

Widener

Plugin ID: rs.maolan.widener

Multiband stereo width processor with independent Low, Mid, and High band controls. Uses LR4 crossovers and mid/side processing per band. Monitor mode for checking stereo, mono, and side signals. Stereo I/O. Best suited for single instruments.

Tone & Character

Saturation, color, and monitoring reference tools.

Saturator

Plugin ID: rs.maolan.saturator

Waveshape saturation with sine-based distortion and intensity-dependent blend. Stereo I/O.

Monitoring

Plugin ID: rs.maolan.monitoring

Monitoring toolbox with 17 reference modes for checking mixes on different playback systems. Stereo I/O.

Instruments & Modeling

Drum sampling and neural amp modeling.

Drust

Plugin ID: rs.maolan.drust

Drum sampler CLAP plugin inspired by DrumGizmo. Async kit loading, MIDI triggering, velocity mapping, round-robin, humanization, per-output balancing, and built-in limiter. 16 mono outputs (Kick L/R, Snare L/R, HiHat L/R, Toms L/R, Ride L/R, Crash L/R, China/Splash L/R, Ambience L/R).

Maolan Kick

Plugin ID: rs.maolan.kick

Percussive synthesizer with layered oscillators and noise. MIDI note-triggered with 16 mono outputs, velocity sensitivity, and a multi-layer DSP engine. Suitable for designing kick and percussion sounds from scratch without sample content.

Rural Modeler

Plugin ID: rs.maolan.ruralmodeler

Neural Amp Modeler (NAM) plugin. Loads neural network amp models and impulse responses. Includes a noise gate, tone stack (Bass/Mid/Treble), input/output calibration, and DC blocking. Mono I/O.

Per-Process Plugin Hosting

Each plugin instance runs in its own isolated OS process. A plugin crash cannot bring down the DAW or stop playback on other tracks.

Crash Isolation

If a plugin segfaults, the OS kills only its host process. The DAW detects the death, mutes the track, and continues playback for all other tracks without interruption.

Shared-Memory IPC

Audio buffers are exchanged through memory-mapped shared memory (<200 µs round-trip per block). Lock-free ring buffers carry parameters, MIDI, and transport state without blocking the real-time audio thread.

DAW-Owned Scheduling

The DAW controls how many worker threads each plugin process may use per audio block. Plugins request work via clap_host_thread_pool; the DAW decides based on global CPU load, eliminating core collisions.

Sample-Accurate Automation

Parameter changes carry an exact sample offset within each block. Automation curves are subdivided into per-sample events and delivered through the IPC ring buffer with no smoothing layer added by the host.

Format Coverage

Out-of-process hosting covers CLAP, VST3, and LV2. CLAP gets native thread-pool sharing; VST3 and LV2 run as single-threaded workers with the same IPC protocol and crash recovery path.

Windows Support

The IPC layer uses CreateFileMapping on Windows and shm_open on Unix. Plugin processes are spawned with CreateProcess and GUI embedding uses SetParent. CLAP and VST3 are supported on Windows; LV2 remains Unix-only.

Plugin Format

All Maolan plugins are distributed as CLAP (CLever Audio Plugin) binaries with embedded Iced GUIs. They support Linux, FreeBSD, macOS, and Windows.

The plugin collection is developed in the plugins repository. UI windowing is handled by baseview, a low-level window system interface for audio plugin UIs.

MixOSC

Rust OSC client and control surface for Behringer X32 and X-Air digital mixers.

mixosc contains two pieces:

  • A desktop GUI built with iced that discovers mixers on the local network and exposes a mixer-style control surface.

  • A Rust library for UDP/OSC discovery, connection probing, state loading, state updates, and meter parsing.

  • 2 components: GUI + library

  • Default X32 UDP port: 10023

  • 7 strip types supported

Maolan Integration

MixOSC is built into Maolan as a dedicated X32 hardware mixer view. When enabled, the full MixOSC control surface runs directly inside the DAW, sharing the same Iced rendering context and widget theme.

How It Works

  • Click the sliders icon in the Maolan toolbar to open the X32 view.
  • Maolan instantiates mixosc::app::StatusApp inside the GUI state.
  • OSC subscription starts only while the X32 view is visible, saving resources.
  • All mixer messages are wrapped as Message::HwMixer and dispatched through the standard update loop.
  • The MixOSC surface renders natively using the same Iced backend as the rest of Maolan.

Technical Details

  • Integrated as View::X32 in the Maolan view state.
  • Uses mixosc::app::subscription for live OSC updates when active.
  • Mixer state is owned by the DAW and updated through mixosc::app::update.
  • The surface view is produced by mixosc::app::view and mapped into Maolan’s message system.
  • Connection to the X32 is handled automatically via UDP broadcast discovery or a configured address.

Supported Mixers

MixerChannelsBusesFX ReturnsDCAsPort
X32 / X32 Compact / X32 Producer / X32 Rack32 + 8 aux168810023
XR18 / XR16 / XR12 / X18 / X16 / X121664 + 1 aux410024

Current GUI Behavior

The application discovers mixers automatically on the local network, connects to every mixer it finds, and opens a tab for each one. You can switch between mixers by clicking their tabs at the top of the window.

When only one mixer is discovered (or when a specific address is given), the tab bar still appears with a single tab.

The control surface loaded in each tab matches the detected model of that mixer.

X32 Layout

  • CH 01-32
  • AUX 01-08
  • BUS 01-12
  • FX 01-08
  • MTX 01-06
  • DCA 1-8
  • Main LR

X-Air Layout

  • CH 01-16
  • BUS 01-06
  • FX 01-04 + AUX
  • DCA 1-4
  • Main LR

For the strips that support them, the UI shows and updates in real time:

  • Name and scribble-strip color
  • Input gain or trim
  • Sends
  • Pan
  • Fader level
  • Input, bus, main/matrix meters, and RTA (Real-Time Analyzer)
  • Mute
  • Solo

The app subscribes to live OSC updates with /xremote and meter subscriptions, so local changes on the mixer are reflected back into the UI.

What Is Implemented per Strip Type

X32

  • Channels and aux inputs: gain/trim, sends to buses 1-16, pan, fader, mute, solo, color, name, meters
  • FX returns: sends to buses 1-16, pan, fader, mute, solo, color, name
  • Buses: sends to matrices 1-6, pan, fader, mute, solo, color, name, bus meters
  • Matrices: fader, mute, color, name, matrix meter
  • DCAs: fader, mute, color, name
  • Main LR: fader, mute, color, stereo meter, RTA

X-Air

  • Channels: headamp gain, sends to buses 1-6, pan, fader, mute, solo, color, name, meters
  • FX returns: sends to buses 1-6, pan, fader, mute, solo, color, name
  • Buses: fader, mute, solo, color, name, bus meters
  • DCAs: fader, mute, color, name
  • Main LR: fader, mute, color, stereo meter, RTA

Implementation details from the current code:

  • Gain uses headamp control where available and trim otherwise.
  • On X32, channel 17-32 use trim gain; earlier channels and supported aux inputs can use headamp gain.
  • On X-Air, all 16 channels have headamp gain.
  • Gain is not exposed for buses, FX returns, matrices, or DCAs.
  • Pan is not exposed for matrices or DCAs.
  • DCA and matrix solo are not sent to the mixer.
  • Master solo is only a local UI toggle right now; it is not sent to the mixer.

Running

Automatic discovery on the local network (connects to all discovered mixers):

cargo run

Connect to a specific mixer only:

cargo run -- 192.168.1.62

You can also include a custom port:

cargo run -- 192.168.1.62:10023
cargo run -- 192.168.1.62:10024

Or use the environment variable:

MIXOSC_MIXER_ADDR=192.168.1.62 cargo run

Default ports:

  • X32: 10023
  • X-Air (XR18, etc.): 10024

When no port is given, the app tries the default ports automatically.

Library Surface

The crate exports OSC helpers from src/common.rs, with model-specific implementations in src/x32.rs and src/xr18.rs:

  • Discovery and connectivity: DiscoveryProbe, ConnectionProbe, DiscoveredMixer, ProbeOutcome
  • Strip state loading and control: FaderBankProbe, PanBankProbe, GainBankProbe, SendBankProbe, MuteBankProbe, SoloBankProbe, NameBankProbe, ColorBankProbe
  • Meter handling: batchsubscribe_meter_request, renew_request, parse_input_meter_packet, parse_main_meter_packet, parse_rta_meter_packet
  • Console update parsing: parse_console_update, ConsoleUpdate
  • Address parsing and constants: parse_target, X32_DEFAULT_PORT, X32_BROADCAST_ADDR, XR18_DEFAULT_PORT, XR18_BROADCAST_ADDR, XREMOTE_REQUEST

This repository has a single binary entry point in src/main.rs and a reusable library in src/lib.rs.

Development

cargo check

Maolan Repositories

All projects and repositories that make up the Maolan ecosystem. Each repository handles a specific layer of the stack.

  • 8 public repositories
  • Rust primary language
  • BSD-2 license
  • CLAP + VST3 + LV2 plugin formats

Core

The foundation of the Maolan DAW.

maolan

github.com/maolan/maolan

The main DAW application. Contains the desktop GUI, session management, and the overall application logic that ties together the engine, widgets, and plugins.

engine

github.com/maolan/engine

The audio engine. Handles audio and MIDI tracks, routing, mixing, plugin hosting (CLAP, VST3, LV2), export, and rendering. Built with Rust and Tokio.

widgets

github.com/maolan/widgets

Shared UI widgets used across Maolan applications. Custom Iced components for meters, faders, piano rolls, and other audio-specific interface elements.

Plugins

Plugin development and windowing infrastructure.

plugins

github.com/maolan/plugins

Maolan plugin collection. Contains rural-modeler and other in-house CLAP plugins, along with build tools and plugin development utilities.

baseview

github.com/maolan/baseview

Low-level window system interface for audio plugin UIs. A fork focused on embedded plugin windowing needs.

Tools

Additional utilities and applications.

generate

github.com/maolan/generate

Maolan AI for generating music. Uses machine learning models to generate audio and MIDI content.

mixosc

github.com/maolan/mixosc

OSC Mixer in Rust. A compact OSC control surface for mixing and transport control.

Site

maolan.github.io

github.com/maolan/maolan.github.io

The source for the Maolan website. Hugo-based documentation and landing pages.

History Coverage Audit

Date: 2026-03-05

Note:

This repository currently includes the audit notes below, but not the helper script that originally generated them. To refresh the audit, compare engine::message::Action against history::should_record manually or add a new local audit script.

Scope

This audit checks engine::message::Action variants against history::should_record. It highlights potential mutating actions that are not currently history-recorded.

Current approach

  • Keep interactive editing/mixing actions undoable.
  • Keep transport/runtime query/report actions non-history.
  • Keep high-frequency automation playback actions non-history to avoid history spam.

Decisions

  • SetLoopEnabled/SetLoopRange/SetPunchEnabled/SetPunchRange/SetRecordEnabled are history-recorded (the previous audit left them as follow-up candidates, but they are now recorded).
  • TrackAutomationLevel/Balance/Mute remain non-history because these are often runtime playback and write-mode side effects.
  • Plugin discovery/query actions (List*, *Parameters, *Graph, *StateSnapshot) remain non-history.
  • MIDI learn arm actions remain non-history; actual binding changes are history-recorded.
  • Tempo / time signature edits are history-recorded via SetTempo, SetTimeSignature, and SetTempoMap.
  • Modulator changes are history-recorded via SetModulators.
  • Track hierarchy changes are history-recorded via TrackSetFolder, TrackSetParent, TrackToggleFolder, and TrackToggleMaster.
  • Clip plugin graph changes are history-recorded via SetClipPluginGraphJson.
  • Automation lane point edits are history-recorded via SetTrackAutomationLanes (lane-level granularity).
  • Pitch correction edits are history-recorded via SetClipPitchCorrection.

Follow-up candidates

If stricter undo semantics are needed, revisit:

  • Granular per-point undo for automation lanes (currently the whole lane snapshot is recorded).
  • Explicit manual-only plugin state restore actions