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

Introduction

Maolan is a digital audio workstation for recording, editing, routing, and producing audio. It is built in Rust as a set of separate components: an audio engine, a graphical application, and command-line tools. This structure lets the engine handle audio work independently of the interface, while the GUI provides the workspace for arranging and managing a session.

Working with sessions

Maolan combines timeline-based recording and playback with non-destructive editing. Your source material remains available while you arrange and refine a session, so you can make changes without treating each edit as a permanent rewrite of the original audio. The engine processes audio and MIDI tracks, routes signals between tracks and plugins, and provides tools for recording, playback, and exporting a finished mix.

The live session view is designed for working with a session as it is being performed. Alongside the timeline, it offers a way to work with session material in a more immediate, performance-oriented setting.

Plugins and audio devices

Maolan supports the CLAP and VST3 plugin formats on its supported platforms, LV2 on Unix systems, and Audio Units (AU) on macOS. Plugins run in separate host processes, which helps keep a plugin failure from taking down the main application. Compatibility depends on the plugin and platform, and support continues to evolve.

Audio device support varies by operating system. Maolan uses ALSA and JACK on Linux, OSS and JACK on FreeBSD, CoreAudio on macOS, and WASAPI on Windows.

Components and platforms

The engine, graphical interface, and command-line tools are maintained as separate libraries and binaries. This gives the project distinct places for audio processing, interactive session work, and command-line operations.

Maolan targets FreeBSD, Linux, Windows, and macOS. Available audio backends and plugin formats differ between these systems, so check the relevant platform notes when choosing devices or plugins.

Audio Latency Calibration

Maolan measures round-trip latency by sending a signal from an audio output through a physical loopback cable and receiving it at an audio input. The maolan-calibrate command-line utility runs this measurement through Maolan’s audio engine on Linux, FreeBSD, macOS, and Windows. It is not limited to OSS devices.

Connect hardware output to an input, then list available devices:

cargo run --bin maolan-calibrate -- --list-devices

Use the device IDs printed by --list-devices in the matching command below. The examples use channel 1; choose channel numbers that match your loopback cable and hardware. If input and output use different devices, supply each device’s ID separately.

Linux (ALSA)

This example selects ALSA card 0, device 0 for both input and output. Replace hw:0,0 with the ID shown for a device that supports both directions:

cargo run --bin maolan-calibrate -- --input-device hw:0,0 --input-channel 1 --output-device hw:0,0 --output-channel 1

FreeBSD (OSS)

Replace /dev/dsp5 with the OSS device ID reported on your system:

cargo run --bin maolan-calibrate -- --input-device /dev/dsp5 --input-channel 1 --output-device /dev/dsp5 --output-channel 1

macOS (CoreAudio)

CoreAudio device IDs are UIDs. Replace the placeholders with the exact UIDs printed by --list-devices for your input and output devices:

cargo run --bin maolan-calibrate -- --input-device "<input-device-UID>" --input-channel 1 --output-device "<output-device-UID>" --output-channel 1

Windows (WASAPI)

WASAPI device IDs look like wasapi:Speakers (X- Device Name). The stream always uses 32-bit float, so omit --bits (values other than 32 are rejected). The number of channels is the device’s current Windows format; if your loopback returns on a higher-numbered channel (for example channel 3 of an 18-channel interface), set that format to enough channels first. Calibration runs in exclusive mode by default (other applications cannot use the device); pass --shared to measure through the Windows mixer instead. Windows also negotiates the period after the request, so each calibration is saved under the period the engine actually negotiated:

cargo run --bin maolan-calibrate -- --input-device "wasapi:Microphone (2- X18/XR18)" --input-channel 3 --output-device "wasapi:Speakers (2- X18/XR18)" --output-channel 1

Tips

Close other applications using the device before calibrating. The utility opens the normal Maolan audio engine and routes its IO Delay generator to the selected output and the selected input to a measurement node. For each supported period, it measures for two seconds, applies the calibration, and saves the playback lead and recording offset before continuing. A period that fails to resolve is reported and skipped.

Defaults are 48,000 Hz, 32-bit audio, two periods, sync mode off, and exclusive mode on: no other application may use the device while calibrating, which keeps the measurement free of mixer interference. Some devices — multichannel USB interfaces in particular — reject exclusive streams; when no period can be calibrated exclusively, the sweep automatically retries in shared mode and says so. Pass --shared to allow sharing the device from the start (on Windows, --bits is rejected unless it is 32, WASAPI’s only format). Use --rate, --bits, --nperiods, --sync-mode, --exclusive, and --shared to configure the device; --gain adjusts measurement input gain. Exact options and device IDs depend on the platform and backend. Use the same engine runtime environment settings when calibrating and running the DAW.

The current saved-calibration configuration is applied when opening FreeBSD OSS and Windows WASAPI devices. It matches the input/output device pair, sample rate, bit depth, period, and mode, and replaces the engine’s input and output latency totals. On Windows the requested period is first resolved to the period the engine negotiates with the device, so the record applies no matter which supported period size the DAW requests. On Linux and macOS the utility can measure latency, but Maolan does not yet reload saved measurements as device latency overrides. Older records from the standalone mmap measurement path are ignored; rerun calibration to replace them with records marked engine_io_delay_v1.

DAW

Maolan provides two ways to work with a session: the Workspace for arranging and mixing over time, and the Live Session view for launching clips in scenes. The Connections view shows the session’s signal routing as a graph. These views use the same tracks and clips, so edits and playback state carry across them.

Workspace

The Workspace is the main arrangement view. Its timeline places audio and MIDI clips along tracks, with a ruler and tempo lane above the arrangement. Use the timeline to position and edit clips against musical time or samples. Tempo and time-signature changes can be placed along the session, and markers help identify important locations. The playhead and transport controls show and control playback; loop, punch, and session ranges define useful timeline regions.

Tracks can contain audio or MIDI material and can be organized in folders. Track controls provide common recording and mix functions such as arm, mute, solo, input monitoring, and level metering. Automation lanes can expose track controls and supported plugin parameters over time. The track area can be filtered and scrolled independently of the timeline.

The mixer sits below the arrangement and provides channel strips with level faders, balance controls, and meters. Its height can be adjusted, and the track, editor, and mixer panels can be shown or hidden to make room for the task at hand. The Workspace also opens focused editors for working with audio and MIDI material.

Live Session

Live Session arranges the session matrix as horizontal track strips. Each strip contains one slot per scene, and the Master strip at the right provides scene controls. Empty slots can be populated with clips; populated slots show the clip name and playback state. Click a slot to launch or stop its clip. Use the scene control in the Master strip to launch the scene’s enabled slots together. The currently playing scene and queued or selected slots are highlighted, so you can see what is active and what is about to launch.

Use the + control in the Master strip to add a scene. Right-click a scene there to rename or remove it. Each scene has its own launch quantization and can carry a tempo. A slot can be configured with a launch mode (Trigger, Gate, Toggle, or Repeat), a launch quantization (None, Beat, Bar, Two Bars, Four Bars, or Eight Bars), and a loop range. These settings control how an individual clip responds when launched; scene quantization controls coordinated launches. Right-click a slot to toggle its participation in scene launches, and middle-click to clear its clip reference. Double-click a populated slot to open the referenced clip in its editor.

Track strips show the track mixer controls alongside the slots, with a Master strip for the hardware output. Select slots or tracks for keyboard actions, and use MIDI learn to bind MIDI controls to slots or scenes. The track strips scroll horizontally when the session is wider than the window. The matrix references the session’s clips, so edits made to a clip are available from both Live Session and the Workspace.

Connections View

Connections View is where you connect separate tracks and hardware ports. Its full graph shows track inputs and outputs alongside the available hardware inputs and outputs. Drag from a compatible output port to an input port to create a route—for example, from a track output to another track’s input, from a hardware input to a track for recording, or from the Master output to hardware speakers. Audio and MIDI ports use different colors, and incompatible port types cannot be connected. Click a connection to select it, use Ctrl-click to change the selection, and disconnect selected routes when needed.

Double-click a hardware endpoint to open the system port connections for the selected backend; with JACK, this opens the JACK Connections view. Select a track to inspect its available connections, or double-click its node to open the focused Connections view. That view also provides access to the track’s Plugin List. Folder tracks expose group input and output ports in the graph, while the internal signal flow through a folder is described in Routing below.

Connections can also be opened for a track from Live Session, which is useful for checking its links to other tracks or hardware while performing. Use the full graph to see and manage connections across the session, or the focused view to work with one track’s endpoints.

Routing

Routing describes how signal flows within a track or folder. A track’s processing graph contains its input, plugin nodes, and output, joined by audio or MIDI connections. Connect compatible ports to choose the processing order, build parallel paths, or route around a plugin. These links determine how the track processes its signal; connections to other tracks and hardware are managed in Connections View.

Folder tracks provide input and output ports that form the boundaries of the group. Within that group, route child tracks and folder ports to define how signals pass through the folder—for example, route several child tracks into the folder’s output so they share the group’s processing path. Folder ports can also be connected internally to create a passthrough. The folder’s outer connections to other tracks or hardware are handled in Connections View.

A track’s internal routing is separate from its mixer level and pan: changing a fader adjusts signal level, while changing a connection alters the processing path. When diagnosing silence or an unexpected result, inspect the track’s processing graph and, for grouped tracks, the folder’s internal routes.

Working With Plugins

Maolan hosts plugins on tracks and, for supported audio clips, within a clip’s processing graph. The plugin graph represents the track or clip input, plugin instances, and output as nodes joined by audio or MIDI connections. Double-click a track in the Workspace to open its plugin graph. The graph view has a track selector and a Plugin List control; clip graphs identify the selected clip in the header. The focused Connections view also provides a Plugin List button for the selected track.

In the graph, drag between compatible ports to route signal through plugins or around them. Move plugin nodes to organize the graph; their positions are retained for the track. Double-click a plugin node to open its plugin interface. Select connection lines to manage plugin routing. This graph is useful for serial or parallel processing, and for checking whether a plugin’s inputs and outputs are connected as intended.

The Plugin List is the place to browse and manage the plugins used by a track. Maolan’s supported formats depend on the operating system: Unix builds support CLAP, VST3, and LV2; macOS also supports Audio Units (AU); Windows supports CLAP and VST3. Plugin compatibility and interface behavior depend on the plugin and host, and may vary. Track and clip plugin graphs are distinct: a track graph processes that track’s signal, while a clip graph stores processing with the clip.

Working With Clips

Audio and MIDI clips are the basic material used in both the arrangement and Live Session. The Clips pane gives you a library view of clips grouped by track, plus an Unused group for clips that are not currently placed on a track. Toggle the pane from the Workspace when you want to find or reuse clip material. Drag a clip from the pane onto a compatible track in the arrangement to place it at the playhead. Dropping a clip from the unused pool places that clip; dragging a clip already on a track makes a new copy. You can also drag clips onto Live Session slots to assign them to scenes.

In the arrangement, select and drag clips to move them, or use Ctrl-drag to copy. Drag an edge to change the clip’s visible bounds; audio clips can also be stretched with Shift-drag on an edge. Fade handles adjust audio fades. Use the timeline snap setting to align edits to bars, beats, subdivisions, clip edges, or freely. Clips can be renamed from their context menu, and double-clicking a clip opens its focused editor.

Audio clips can be opened in Maolan Edit for waveform work such as selecting a range, applying fades or gain, reversing audio, deleting material, or replacing a selection with silence. The embedded editor keeps edits associated with the session clip; use the editor’s undo and redo controls to review changes.

MIDI clips open in the piano roll, where notes can be created, selected, moved, resized, and edited alongside controller lanes. The piano roll supports quantizing, humanizing, and applying groove to selected notes. Audio and MIDI clips can both be launched from Live Session, while the arrangement provides precise placement and editing along the timeline.

Grouped clips can keep related material together when arranging or reusing it. The Clips pane avoids listing the same clip more than once when it is referenced in multiple places, so the unused pool and track lists remain easier to scan.

Modulators

Modulators generate changing control values that can be assigned to track parameters. Toggle the Modulators pane from the Workspace, then press + to create one. Select a modulator card to make it the active source for assignments. Give it a name, turn it on or off with its checkbox, and remove it with ×.

Choose a waveform shape—Sine, Triangle, Saw, Square, or Sample & Hold—and set its phase. The rate can run at a frequency in hertz or follow the session tempo using a musical division from a bar down to a sixty-fourth note. Use a free-running rate when modulation should have a fixed speed, or a musical rate when it should stay aligned to the tempo.

With a modulator selected, assign it from a track’s volume or balance control, or from a visible automation lane for a supported parameter. Assignments can target track volume and balance, MIDI CCs, and supported plugin parameters. The target dialog lets you set the minimum and maximum values the modulator will span; use Remove in that dialog to clear an existing assignment. Assigned controls are highlighted in the track or mixer UI, making it easier to see which parameters the selected modulator affects.

Modulator settings and assignments are stored with the session. Keep the pane open while assigning targets; hiding it clears the active selection, while leaving the modulators and their assignments in the session.

Export, Ranges and Formats

Open Export Settings to render the session to files. Choose one or more output formats—WAV, FLAC, MP3, or OGG—and select the sample rate. Available bit-depth choices depend on the selected formats; WAV-style PCM options include 16-, 24-, and 32-bit integer PCM and 32-bit float. Dither can be set to None, Rectangular, or Triangular when the chosen output supports it.

Choose Mixdown to render the selected hardware output channels together as a single mix. The dialog lets you choose which hw:out ports to include. Choose Stems (Pre-Fader) or Stems (Post-Fader) to render separate outputs for track output channels; pre-fader stems bypass track fader levels, while post-fader stems include them. Stem exports use one channel per track output port.

The range setting controls which part of the session is rendered: Session, Loop, Punch, or All. Session, loop, and punch exports use their corresponding timeline ranges; All renders from the start through the full session content. Set loop or punch boundaries in the Workspace before choosing those ranges.

Create ranges in the Workspace by dragging across the timeline with the left mouse button. Drag in the top ruler to create a loop range. Drag in the session-range lane of the timing area to set the session range, or drag in the punch area to set the punch range. The current snap mode applies to the new boundaries, so choose a bar, beat, subdivision, clip-edge, or no-snap mode before drawing when you need a particular alignment.

To move an existing range without changing its length, middle-drag from inside it. To resize it, middle-drag near its start or end edge. These gestures work for loop, session, and punch ranges in their respective lanes. After creating a loop or punch range, use its toolbar button to turn looping or punch recording on and off; setting the range alone does not activate the mode.

Optional processing includes peak normalization to a dBFS target or loudness normalization to a LUFS target with a true-peak ceiling. Loudness normalization can use a true-peak limiter, and the export dialog also offers a separate master limiter with a dBTP ceiling. A real-time fallback render is available for cases where rendering through the normal offline path is unsuitable. Once the settings are ready, choose Export and save the rendered output.

Markers, Tempo and Signature

The timing area above the tracks contains the marker ruler, tempo lane, and time-signature lane. Markers label locations in the session and make it easier to navigate between sections. Press N to create a marker at the playhead, or right-click an empty spot in the marker ruler to create one there. Right-click an existing marker to rename it.

Add a tempo point by middle-clicking an empty spot in the tempo lane, and add a time-signature point by middle-clicking an empty spot in its lane. Each point changes the session timing from its position onward. Select a point to edit its BPM or numerator and denominator in the timing controls. Shift-click adds points to the selection; drag selected points horizontally to move them. The current snap mode controls their placement.

Right-click a tempo or time-signature point to open its context menu. Duplicate copies the selected points, Reset restores their values from the previous point, and Delete removes them. The timing controls also provide these actions and a Clear button for deselecting points. Changes to tempo and meter affect the bar and beat ruler and any tempo-synced playback or modulation.

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>", and "au_<id>" (macOS).

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", or "au"), plugin ID. AU is available on macOS; LV2 is available on Unix.
  • /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 [i] — track_name, format, instance_id, directory, optional shared flag (0/1, default 1)
  • /plugin/collect_resources s s i — track_name, format, instance_id; CLAP only. Asks the plugin to copy its external files into the resource directory set by set_resource_dir
  • /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 — format supports CLAP, LV2, and AU (AU on macOS)
  • /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 [i] — directory plus optional shared flag (default 1)
  • /clip_plugin/collect_resources s s i i — CLAP only; see /plugin/collect_resources

Plugin graph node strings:

  • "track_input"
  • "track_output"
  • "clap_<instance_id>"
  • "vst3_<instance_id>"
  • "lv2_<instance_id>"
  • "au_<instance_id>" (macOS)

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

Create a text file with one command per line and pass it to maolan-osc --file.

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.stereo"
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 set_resource_dir "Drums" clap 0 "/path/to/session/data" 1
cargo run --bin maolan-osc -- plugin collect_resources "Drums" clap 0

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.

  • 23 exported variants
  • 22 distinct products
  • Iced TokyoNight GUI
  • BSD-2 license

Instruments

Drums

Drums GUI

Plugin ID: rs.maolan.drums

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

Kick

Kick GUI

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.

Random

Random GUI

Plugin ID: rs.maolan.random

A singing practice MIDI source that emits a random reference pitch, pauses for you to sing it back, and repeats while the session transport plays. It generates MIDI notes within the selected range (C3 to C5 by default), with no consecutive repeated pitches unless the range contains only one note. No MIDI input or audio output is needed.

The Note length and Pause length dropdowns control their durations independently: 1/16, 1/8, 1/4, 1/2, or whole notes, and 1, 2, or 4 bars. Both default to one bar. Note values follow the session tempo; bars also follow its time signature (one bar is three quarter notes in 3/4 or six eighth notes in 6/8). Stopping sends a MIDI note-off if a generated note is active; starting begins a new note and pause cycle. Generated MIDI notes use channel 1 and velocity 100. Route the MIDI output to an instrument to hear the reference pitch.

Lowest note and Highest note set the inclusive pitch range, using note names from C-1 to G9 (middle C is C4). The dropdowns keep the lowest note at or below the highest note. Choose the same note in both to practice one pitch repeatedly. Range changes apply to the next note, and all four settings are saved with the session.

Sampler

Sampler GUI

Plugin ID: rs.maolan.sampler

Polyphonic sample player supporting SFZ (v1/v2) and SoundFont 2 (SF2.01/SF2.04) instruments in addition to standalone WAV files.

  • SFZ Format Engine: Includes preprocessor for #include relative path imports, #define macros, #if/#else/#endif blocks, and header scope precedence (control → global → master → group → region). Supports core v1/v2 opcodes for key/velocity mapping, key crossfades, tuning, panning, loops, playback directions, keyswitches, round-robin / random variants, envelope generators, LFOs, and multimode filters.
  • SoundFont 2 (SF2) Engine: Parses RIFF SoundFont files with 16-bit and 24-bit PCM sample data, INFO metadata, multi-preset bank structures, generator hierarchy merging (GeneratorSet), and default/custom imod modulators mapped to the modulation matrix.
  • Background Loading: Instrument parsing and resample rendering occur asynchronously on a background worker thread. New patches swap into the audio engine atomically (AtomicArc) without interrupting active voices or causing audio dropouts.
  • Interactive GUI: Supports drag-and-drop file loading, bank/preset dropdown selection, real-time loading progress indicator, instant reload button for SFZ editing, and scrollable diagnostic error logging.

Synth

Synth GUI

Plugin ID: rs.maolan.synth

Polyphonic synthesizer inspired by Surge XT. Features three oscillators with multiple synthesis modes (including wavetable, FM, and physical-modeling flavors), two multimode filters with configurable routing, three envelopes, six LFOs, a 12-slot modulation matrix, an MSEG, a step sequencer, noise and waveshaper sections, and microtonal tuning support. Stereo I/O.

Parameter groups

GroupDescription
Osc1–Osc3Type, octave, semitone, fine, shape, skew, formant, level, unison, sync, sub, routing, solo/mute
Filter1–Filter2Type, subtype, cutoff, resonance, EG amount, key tracking, drive, feedback, enable
FilterFilter routing and balance
AmpEG / FilterEG / PitchEGAttack, decay, sustain, release, mode, shapes, retrigger, tempo sync, uber release
LFO1–LFO6Rate, shape, amount, deform, trigger, sync mode/division, envelope, phase, unipolar
ModFixed mod depths (velocity/key/LFO to filter, mod wheel/aftertouch to filter)
ModRoute1–12Source, target, depth, curve
NoiseType, level, color, filter, stereo, enabled
WaveshaperShape, drive, mix, enable
FlavorAdditional filter-like flavor stage
Step Seq16 step values, loop start/end, shuffle, trigger targets
MSEG128 nodes, 127 segment curves, loop, retrigger targets
MacrosMacro1–8 modulation sources
MasterVolume, pan, width, polyphony, portamento, pitch-bend range, play mode, voice priority
TuningScale, root, SCL index
FM / Twist / String / AliasOscillator-specific parameters for FM, twist, string, and alias engines

Effects

Chorus

Chorus GUI

Plugin ID: rs.maolan.chorus

Multi-voice stereo chorus with modulated delay lines. Even voices read from the left channel and odd voices from the right, producing a wide stereo image.

Parameters

ParameterRangeDefaultDescription
Mod Depth0.0 … 10.0 ms5.0LFO delay modulation depth
Mod Rate0.1 … 5.0 Hz0.5LFO rate
Dry/Wet0.0 … 1.00.5Mix balance
Voices2 … 168Number of chorus voices

Compressor

Compressor GUI

Plugin ID: rs.maolan.compressor

Multiband compressor with LR4 crossovers. Peak/RMS sidechain, FabFilter Pro-MB-style Compress/Expand modes with signed Range, lookahead, sidechain boost, and classic/modern topology. Double-click the spectrum display to add bands. Drag crossover lines to move splits. Drag the white gain contour to adjust Gain/Makeup for the band under the cursor; middle-drag it to adjust Range; right-drag it to adjust Threshold. Drag the yellow contour to adjust Range directly, or the blue contour to adjust Threshold directly. Negative Range draws below gain and positive Range draws above it.

DeEsser

DeEsser GUI

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.

Delay

Delay GUI

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.

Formant

Formant GUI

Plugin ID: rs.maolan.formant

Vowel formant filter using three constant-Q bandpass biquads per channel. The Vowel control crossfades between the A, E, I, O, and U vowel tables for continuous timbre shaping.

Parameters

ParameterRangeDefaultDescription
Vowel (A-E-I-O-U)0.0 … 4.00.0Vowel selector with interpolation
Sharpness (Q)2.0 … 40.02.0Bandpass filter Q
Output Gain−60.0 … 20.0 dB0.0Output gain

Flanger

Flanger GUI

Plugin ID: rs.maolan.flanger

Stereo flanger with LFO-modulated delay lines and a separate feedback path, ported from LSP Plugins’ Flanger Stereo algorithm. Offers 13 LFO shapes (plus off) with independent right-channel LFO, tempo-synced rate, wrap crossfading, mid/side processing, and feedback with drive and delay. The Stereo switch selects stereo (2 audio ports, default) or mono (1 audio port) I/O and asks the host to rescan audio ports when changed; the stereo-only parameters (LFO 2, Phase difference L/R, Mid/Side) apply when Stereo is on.

Parameters

ParameterRangeDefaultDescription
StereoOff / OnOnSwitch between stereo (2 audio ports) and mono (1 audio port) I/O
Rate0.01 … 20.0 Hz0.25LFO rate
Tempo20 … 360 BPM120Tempo for tempo time mode
Tempo SyncOff / OnOffRead BPM from host transport
Time ModeRate / TempoRateHow the LFO rate is determined
Time Fraction1/64 … 81Note fraction for tempo mode
Crossfade0 … 50 %0Wrap crossfade length (fraction of half cycle)
Crossfade TypeConst power / LinearConst powerAudible crossfade law (feedback always linear)
LFO Type13 shapes + OffTriangularLeft channel LFO shape
LFO PeriodFull / First / LastFullPortion of the LFO cycle used
LFO2 TypeSame + 13 shapes + OffSameRight channel LFO shape
LFO2 PeriodFull / First / LastFullRight channel LFO period
Initial Phase0 … 360°0LFO phase after reset
Phase Diff L/R0 … 360°0Phase shift between channels
Reset Phasetrigger—Restart the LFO at the initial phase
Mid/SideOff / OnOffProcess mid and side independently
Min Depth0.01 … 10.0 ms0.25Minimum delay
Depth0.1 … 20.0 ms2.0LFO delay sweep depth
Signal PhaseOff / OnOffInvert the wet signal polarity
Feedback OnOff / OnOffEnable the feedback path
Feedback Gain0.0 … 0.891250.5Feedback amount (−6 dB default)
Feedback Drive0.0 … 1.00.0Input drive into the feedback path
Feedback Delay0.0 … 5.0 ms0.0Extra feedback path delay
Feedback PhaseOff / OnOffInvert feedback gain and drive
Input Gain−24.0 … 24.0 dB0.0Input gain
Dry/Wet0.0 … 1.00.5Dry/wet mix balance
Output Gain−24.0 … 24.0 dB0.0Output gain

Limiter

Limiter GUI

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.

Modeler

Modeler GUI

Plugin ID: rs.maolan.modeler

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.

Parametric EQ

Parametric EQ GUI

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. Middle-drag a selected bell band dot to create or adjust its dynamic range target. Input and output gain with global bypass. Mono or stereo I/O depending on host channel count.

Using the EQ graph

  • Double-click an empty spot in the graph to create a bell band there. The horizontal position sets its frequency and the vertical position sets its gain. The new band is selected; drag its node to adjust frequency and gain. Hold Shift while dragging the node vertically to adjust Q.
  • To add dynamics to a selected bell band, middle-drag its node vertically. The node’s starting level sets the threshold; the drag position sets the dynamic target. The band then responds when its detected level crosses the threshold. Middle-drag again to adjust the target. Dynamic targets are available for bell bands.
  • To remove the selected band, click Delete.

Phaser

Phaser GUI

Plugin ID: rs.maolan.phaser

Modulated all-pass cascade phaser. The LFO sweeps the center frequency of up to 12 first-order all-pass stages. Feedback can be taken from the previous output or from a configurable delay line.

Parameters

ParameterRangeDefaultDescription
LFO Rate0.01 … 2.0 Hz0.1LFO rate
LFO Depth0.0 … 1.00.5LFO modulation depth
Manual (Center)0.0 … 1.00.5Manual center position
Feedback−0.98 … 0.980.0Feedback amount
Feedback Delay On0 / 10Use delay-line feedback instead of previous output
Delay Time0.0 … 20.0 ms1.0Feedback delay time
Stages (All-pass)1 … 1212Number of all-pass stages

Reverb

Reverb GUI

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.

Saturator

Saturator GUI

Plugin ID: rs.maolan.saturator

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

Stereo

Stereo GUI

Plugin ID: rs.maolan.stereo

Multiband stereo width processor with four sections: Gain, Delay, Character, and Output. 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.

  • Gain — per-band width gains (Low/Mid/High), crossover frequencies (X1, X2), and the global side Boost.
  • Delay — per-band Haas-style delays (Low/Mid/High Delay) with a shared Strength control.
  • Character — sin/cos mid/side density with offset delay, inherited from the former Stereo plugin design. Density shapes the side, Focus the mid, and Amount sets the effect mix.
  • Output — output Volume, Monitor Mode (Stereo/Mono/Side), and per-band solos.

Each of the Gain, Delay, and Character sections can be switched on or off from the GUI with the section switches (Gain, Delay, Character Off/On toggles at the head of each section). The switches are GUI-only controls; they are not automatable parameters. When both Gain and Delay are switched off, the crossover band split is bypassed entirely and the signal goes straight to the Character section (or to the output when Character is off as well).

Tuner

Tuner GUI

Plugin ID: rs.maolan.tuner

Monophonic pitch tuner using the YIN algorithm. Adjustable reference pitch and clarity threshold for reliable pitch detection.

Parameters

ParameterRangeDefaultDescription
Reference Hz420.0 … 460.0440.0Tuning reference frequency
Clarity Threshold0.0 … 1.00.7Minimum clarity for pitch detection

VU

VU GUI

Plugin ID: rs.maolan.vumeter

Stereo VU meter for diagnostics. Two audio inputs (Left/Right) with ballistics-style VU displays and no parameters. Use it to monitor signal levels on any channel.

Vocoder

Vocoder GUI

Plugin ID: rs.maolan.vocoder

24-band filter-bank vocoder. Each band has its own envelope follower that shapes the band-limited signal before summing. Spectral Shift transposes the entire filter bank.

Parameters

ParameterRangeDefaultDescription
Spectral Shift0.5 … 4.00.5Filter-bank frequency shift multiplier
Dry/Wet0.0 … 1.01.0Mix balance

Wah

Wah GUI

Plugin ID: rs.maolan.wah

Resonant wah-wah filter with pedal, LFO, and envelope follower modes. The filter sweeps a resonant lowpass/bandpass-style response between Min and Max Cutoff, driven manually by the Position control, automatically by an LFO, or by the input signal envelope.

Parameters

ParameterRangeDefaultDescription
Mode0.0 … 2.00.0Sweep mode (Pedal / LFO / Envelope)
Min Cutoff50.0 … 2000.0300.0Minimum filter cutoff
Max Cutoff500.0 … 10000.03000.0Maximum filter cutoff
Resonance0.1 … 10.04.0Filter resonance
Position0.0 … 1.00.5Manual pedal position
LFO Rate0.1 … 20.02.0LFO rate
LFO Depth0.0 … 1.00.5LFO modulation depth
LFO Shape0.0 … 3.00.0LFO waveform
Env Attack1.0 … 500.020.0Envelope follower attack time

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. Extra widgets are implemented as part of maolan-widgets repository.

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 Editor

Maolan Edit is a waveform editor built as a reusable Rust crate. It runs as a standalone application and its interface can also be embedded in Maolan, where it is used to inspect and edit audio within a session. The editor shares Maolan’s audio decoding, encoding, and UI components.

Working with audio

Open an audio file to view its waveform, select a range, and preview playback. Edits include fades, gain changes, reverse, deleting a selection, and replacing a selection with silence. Changes can be undone and redone. The editor also supports moving the playhead, jumping to a zero crossing, and working with markers to identify useful regions in a file.

Marker ranges can be exported as separate audio files. Export options include the output format, bit depth where applicable, and sample rate. The editor can also save the edited audio as a new file, leaving the original available if a different output path is chosen.

Audio formats

The open dialog supports WAV, FLAC, MP3, Ogg/Vorbis, and M4A/AAC/ALAC files. Export supports WAV, FLAC, Ogg FLAC, and MP3. Unsupported output extensions are rejected. Available format details and options may vary by export format.

Standalone and embedded use

As a standalone application, Maolan Edit can open files, play them through a configured audio device, edit and save them, and export marker ranges. When embedded in Maolan, the editor can open a session audio clip for waveform-based editing. Clip edits are stored as actions in the session and remain non-destructive; save the session to keep them. The DAW connects the editor to session playback and handles loading the clip, while the standalone application manages its own file and device workflow.

Maolan Engine

maolan-engine is the audio and MIDI processing library used by the Maolan DAW. It is a separate Rust crate, so other Rust applications can also build on it. The engine handles device IO and session processing; Maolan’s graphical interface and command-line tools communicate with it through messages.

What it does

The engine processes audio and MIDI tracks for recording, playback, and timeline editing. Tracks can be routed to other tracks and through plugin graphs. It also provides automation and modulation processing, audio and MIDI recording, clip playback, and helpers for offline rendering and export.

Track work is distributed across engine workers. A render plan describes the work for an audio cycle, including track dependencies and routing, so independent work can run in parallel while connected tracks retain the required processing order. The engine also supports offline rendering, where audio can be processed without running against a live device clock.

Audio backends

The available device backend depends on the operating system:

Operating systemAudio backends
LinuxALSA, JACK
FreeBSDOSS, JACK
macOSCoreAudio
WindowsWASAPI

Sample rates, buffer sizes, channel counts, and device selection depend on the backend and hardware. Maolan’s device settings expose the options available for the selected device.

Plugin hosting

CLAP, VST3, LV2 (on Unix systems), and Audio Unit (on macOS) plugins run in separate host processes, one process per plugin instance. The engine and plugin host exchange audio, MIDI, parameter, and state data through shared memory and lightweight inter-process events. Keeping plugin code outside the DAW process means a plugin crash can be isolated: the engine can detect the failed host, bypass that plugin, and keep the main application running.

Using the engine from another application

maolan-engine is an independent Rust crate that applications can add as a Cargo dependency. A host application can provide its own interface and use the engine for device IO, audio and MIDI processing, routing, plugin hosting, and offline rendering without embedding the Maolan DAW interface.

Applications control the engine through its message interface: send requests to open devices, control transport, and edit tracks, then handle the resulting events and state updates. The crate also exposes reusable modules for audio codecs, MIDI, routing, plugin interfaces, render plans, and worker execution. Consult the maolan-engine crate documentation for the public API and platform-specific modules available to your application.

AI and Generative Tools

Maolan includes tools for generating audio and MIDI from prompts, along with neural analysis and resynthesis for pitch correction. Generated material is created inside an open session and added to the arrangement as a new track.

Audio generation

The audio generator offers two model families:

  • HeartMuLa provides the happy-new-year and RL model options. It generates music from a text or lyrics prompt, with optional style tags.
  • ACE-Step 1.5 provides acestep-turbo and acestep-sft options for prompt-driven instrumental generation. The turbo option also lets you choose a language-model planner size.

The generator can condition output on tempo, key, and time signature. You can also adjust duration and generation settings such as guidance scale and step count. Generated audio is imported into the session as a new audio track.

Generation runs on the CPU or Vulkan backend. Model weights are not bundled with Maolan and may need to be downloaded on first use; model availability and hardware requirements vary by model and backend.

MIDI generation

Maolan offers two prompt-to-MIDI approaches:

  • Text to MIDI interprets prompt details such as tempo, key, time signature, instrument, and style, then creates a MIDI sequence deterministically without loading a neural model.
  • MIDI-LLM uses a Llama 3.2 1B checkpoint fine-tuned with a music-token vocabulary to generate MIDI from a text prompt.

Both options can use tempo, key, and time-signature settings. MIDI-LLM also provides token limit and sampling controls; Text to MIDI provides sequence length and seed settings. Generated MIDI is imported as a new MIDI track.

Neural pitch correction

Pitch correction can analyze a vocal clip with the FCPE pitch detector. In resynthesis mode, Maolan uses the PC-NSF-HiFiGAN vocoder to render audio using the edited pitch contour while retaining the source timbre. Model weights are downloaded when needed. This mode requires a working Vulkan GPU; there is no CPU fallback for the neural pitch models.

Maolan also includes non-neural pitch correction modes. See Keyboard Shortcuts and Gestures for how to open and edit pitch correction in the application.

Maolan Shortcuts and Gestures

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

Audio Editor

  • Escape: Close the audio editor (same as the toolbar × button); when an editor dialog is open, the dialog is cancelled instead

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

Plugin Editors

  • Maolan EQ: Middle-drag the selected bell band dot to create or adjust its dynamic range target
  • Maolan Compressor: Left-drag the white gain contour to adjust Gain/Makeup; middle-drag it to adjust Range; right-drag it to adjust Threshold. The yellow contour adjusts Range directly, and the blue contour adjusts Threshold directly.

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.

Notes

  • Current keyboard handling is Ctrl-based in code paths.
  • 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 code paths.