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

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