Remote Control Overview

The M-32 DA Pro II can be remote controlled. Remote control is activated by default and is not affected by preset changes or device lock.

The network controls over HTTP and ATDECC operate simultaneously. Two or more controller instances are synchronized. The MIDI control communicates either via DIN or embedded into either one of the MADI signals. Both network and MIDI control can be used at the same time.

The remote control protocols are not protected against malicious use. When activated, the remote control server allows anyone on the network to make changes to the configuration of the device. To limit access, secure the network that the device is connected to.

Finding the Device on a Network

The M-32 DA Pro II has three integrated network adapters (USB 2.0 and dual ethernet).

The adapters can be used, individually or simultaneously, to control the device with HTTP ("web remote"). The web remote control works on any IP-based network, including wireless networks.

The ethernet connection additionally supports ATDECC 1722.1 remote protocol, which requires a physical connection (cables), but does not require AVB switches. Wireless routers are not supported for ATDECC.

To enable web remote functionality over HTTP:
  1. Open the remote tab in the STATE section.

    Remote Tab
  2. Ensure that the HTTP Remote setting is switched to wAL ToggleOnSmall ON.

USB

When the device is connected with a USB 2.0 cable to a Apple macOS™ or Microsoft Windows™ computer, a network device is automatically installed in the background that assigns the M-32 DA Pro II the following IP address:

Only one of the following products can be connected to the host computer via USB at a time: RME M-32 AD Pro (II, II-D), M-32 DA Pro (II, II-D), 12Mic, 12Mic-D, AVB Tool, M-1610 Pro, M-1620 Pro.

Ethernet

The integrated ethernet adapter will join an IP network when connected. If no DHCP server is found, for example when connecting the M-32 DA Pro II directly to a computer, an address is automatically self-assigned (in the 169.254.0.0/16 subnet).

To find out the current IP address:
  1. Open the network tab in the STATE section.

    Network Tab
  2. The current IP addresses of both networks are displayed.

  3. Enter the IP address of the corresponding network in the address bar of the browser.

Connecting to the Remote Interface without IP address

Instead of using the IP address, the device name can be entered in the browser window, followed by .local/.

The current device name is shown on the standby screen between the 'Clock' and 'Output' sections. It may be abbreviated if it does not fit in the corresponding space.

By default, the name is m32-da-pro, and the corresponding URL is therefore:

The length of the custom name should not exceed 63 characters. Spaces, underscores and other special characters in the device name should be written as hyphens ("-") when entering the URL.
on some operating systems or browsers, a trailing dot "." may be required after the 'local' domain: http://m32-da-pro.local./
The device name is stored in a preset. Loading a preset can therefore change the device name and require a different address.

Web Remote

An integrated web server provides an easy-to-use remote control interface for the M-32 DA Pro II. It requires a network connection from a desktop or tablet computer with a current browser version.

Compatible browsers:
  • Chrome 127

  • Firefox 127

  • Edge 127

  • Safari 17.0

    or newer with support for WebGL.

Web Remote Overview

wDA 151 3C 1

wAL co 1

Firmware Update

wAL co 2

Identifying a Device Remotely

wAL co 3

Power State

wAL co 4

Presets

wAL co 5

Front Panel Illumination

wAL co 6

OUTPUT Section

wAL co 7

CLOCK Section

wAL co 8

INPUT Section

wAL co 9

Analog Outputs

wAL co 10

OUTPUT Section

JSON(OSC) Remote Control

This topic describes a method for remote control modeled losely after the Sennheiser® Sound Control protocol. Detailed background information on the underlying technology can be found on the Sennheiser® website.

The M-32 DA Pro II can be remote controlled with HTTP POST requests. Each request carries a data payload that contains a JSON object modeled after the open sound control (OSC) protocol.

For example, if the device is connected to a computer that can run cURL in a terminal application (Microsoft Windows™ PowerShell or Apple macOS™ Terminal), the following command will request the entire device schema as a JSON object:

Request:
curl --header "Content-Type: application/json" --request POST --data '{"osc":{"schema":null}}' m32-da-pro.local/api/v2/self
Response:
{
    "osc": {
        "schema": {
            "osc": {
                "version": null,
                "schema": []
            },
            "device": {
                "entity_id": null,
                "entity_model_id": null,
                "entity_capabilities": null,
                "entity_name": null,
                "vendor_name": null, (1)
                "model_name": null,
                "firmware_version": null,
                "group_name": null,
[... continues]
1 "vendor_name" Object

This schema can then be used to identify the possible parameters, for example the vendor name. Sending an empty value null triggers a response with the current value of the requested object.

The first two levels of the schema ({"osc": {"schema": {…​}}}) must be omitted. Only the encapsulated objects (device, input, output, routing etc.) are used.

To request the "vendor_name" object of the connected device, we run the following command. It is here outlined in more detail.

Request of vendor name:
curl \  (1)
 --header "Content-Type: application/json" \ (2)
 --request POST \ (3)
 --data '{"device": {"vendor_name": null }}' \ (4)
 m32-da-pro.local/api/v2/self (5)
1 cURL command to send an HTTP POST request
2 header: application/json
3 request type "POST"
4 JSON object sent to the device, 'null' to get current value
5 URL or IP of the device on the network with path to API

Executing this command delivers the expected result:

{"device":{"vendor_name":"RME Audio"}}
The entire web remote application is based on this protocol. It is therefore possible to read the data payloads sent to the device when interacting with the web remote by using the "Network"-tab of the developer tools inside the browser.

All device values must be polled by sending the corresponding JSON objects. It is possible to poll or set several values at once in a single object:

Set phase "on" for analog inputs 1-4
--data {"input":{"analog":{"1":{"phase":true},"2":{"phase":true},"3":{"phase":true},"4":{"phase":true}}}}

JSON(OSC) Implementation Chart

/osc/schema

TX: {"osc": {"schema": null}}
RX: {"osc": {"schema": {[...]}}}

Retrieves the entire device schema, which can then be used to poll all current values from the device by stripping the outer {"osc": {"schema":{ and }}}.

/device

Objects that reflect or affect the overall device state except clock, I/O and routing.

/device/entity_id

TX: {"device": {"entity_id": null}
RX: {"device": {"entity_id": "0x480bb2fffed00ad4"}}

Returns a unique EUI-64 as the devices Entity ID according to IEEE 1722.1 ATDECC as a string.

/device/entity_model_id

TX: {"device": {"entity_id": null}
RX: {"device": {"entity_id": "0x480bb2fffed70300"}}

Returns a unique EUI-64 as the devices Entity Model ID according to IEEE 1722.1 ATDECC as a string.

/device/entity_capabilities

TX: {"device": {"entity_capabilies": null}
RX: {"device": {"entity_capabilities":"0xc588"}

Returns AVB device capabilities according to IEEE 1722.1 ATDECC.

/device/entity_name

TX: {"device": {"entity_name": null}
RX: {"device": {"entity_name": "M-32 DA Pro II"}
TX: {"device": {"entity_name": "New Name"}}

Retrieve or set the current device name. Since the device name is reflected in the URL (when using Bonjour), it may be necessary to change the following commands to match the new device URL.

/device/vendor_name and /device/model_name

TX: {"device": {"vendor_name":null,"model_name":null}
RX: {"device": {"vendor_name":"RME Audio","model_name":"M-32 DA Pro II"}

Retrieve vendor and product name.

/device/firmware_version

TX: {"device": {"firmware_version":null}
RX: {"device": {"firmware_version":"fw 2.6.1"}}

Shows the firmware version currently installed on the device.

/device/group_name

TX: {"device": {"group_name": null}
RX: {"device": {"group_name": "RMEnet"}
TX: {"device": {"group_name": "New Group"}

Retrieve or set the current IEEE 1722.1 ATDECC group name.

/device/identify

TX: {"device": {"identify": null}
RX: {"device": {"identify": false}
TX: {"device": {"identify": true}

Trigger LED flashing on the front panel of the device.

/device/psu/state

TX: {"device": {"psu": {"state": null}}}
RX: {"device": {"psu": {"state": [true, true]}}}

Returns the state of the internal power supplies.

/device/psu/redundancy_alert

TX: {"device": {"psu": {"state": null}}}
RX: {"device": {"psu": {"state": false}}
TX: {"device": {"psu": {"state": true}}}

If the value is set to true, the device signals a warning when one of the power supplies does not operate. This is then reflected in the following object

RX: {"device": {"psu": {"soundness": {"state": "Good"}}}}

/device/levelmeters

TX: {"device": {"levelmeters": {"mode": null}}} (1)
RX: {"device": {"levelmeters": {"mode": "rms"}}} (2)
TX: {"device": {"levelmeters": {"mode": "peak"}}} (3)
1 Request current levelmeter display value
2 Response: current value is "rms"
3 Set the levelmeter mode to "peak"
TX: {"device": {"levelmeters": {"over_hold": null}}} (1)
RX: {"device": {"levelmeters": {"over_hold": "off"}}} (2)
TX: {"device": {"levelmeters": {"over_hold": "auto"}}} (3)
1 Request status of continuous clipping notification
2 Response: current value is "off"
3 Hold clip events (valid values: "on", "auto" reset, "off")
TX: {"device": {"levelmeters": {"over_reset": true}}} (1)
1 If the clip events are currently displayed continuously, reset the notification for all channels.

/device/dark_mode

TX: {"device": {"dark_mode": {"display": null}}} (1)
RX: {"device": {"dark_mode": {"display": false}}} (2)
TX: {"device": {"dark_mode": {"display": true}}} (3)
1 Request status of display dark mode
2 Response: the display is currently on, dark mode is off.
3 Set the dark mode for the display to "true"
TX: {"device": {"dark_mode": {"power_led": null}}} (1)
RX: {"device": {"dark_mode": {"power_led": false}}} (2)
TX: {"device": {"dark_mode": {"power_led": true}}} (3)
1 Request status of power LED dark mode
2 Response: the LED is on, dark mode is off.
3 Turn off the LED.
TX: {"device": {"dark_mode": {"levelmeter_leds": null}}} (1)
RX: {"device": {"dark_mode": {"levelmeter_leds": "on"}}} (2)
TX: {"device": {"dark_mode": {"levelmeter_leds": "dim"}}} (3)
1 Request status of the front panel level meter LEDs
2 Response: the LEDs are on, dark mode is off
3 "dim" or turn "off" the level meter LEDs
TX: {"device": {"dark_mode": {"soundness": null}}} (1)
RX: {"device": {"dark_mode": {"soundness": "Inactive"}}}
1 Request whether any of the preceding settings is set to true or "off"
The Soundness is set to "Caution" when /dark_mode/display or /dark_mode/power_led are set to true, or if /dark_mode/levelmeter_leds is set to "off".

/device/preset

TX: {"device": {"preset": {"active": null}}} (1)
RX: {"device": {"preset": {"active": 0}}} (2)
1 Request current preset
2 Response: current preset is unsaved (0), or one of presets 1-16
TX: {"device": {"preset": {"loaded": null}}} (1)
RX: {"device": {"preset": {"loaded": 16}}} (2)
1 Request last loaded preset
2 Response: current state is based on preset 16 (or 1-15)
TX: {"device": {"preset": {"soundness": null}}} (1)
RX: {"device": {"preset": {"soundness": {"state": "Notice","cause": "PresetChanged"}}}} (2)
1 Request preset soundness
2 Response: Notice: current preset was changed
TX: {"device": {"preset": {"save": 4}}} (1)
RX: {"device": {"preset": {"save": 4}}} (2)
1 Store current device state into Preset 4 (or 1..15)
2 Response: 200 OK, current state stored
TX: {"device":{"preset":{"recall": 5}}} (1)
RX: {"device":{"preset":{"recall": 0}}} (2)
1 Load preset 5 (or 1..16, 16 represents factory preset)
2 Response: 200 OK, preset loaded

/device/health

TX: {"device": {"health": {"temperatures": {"core": null}}}} (1)
RX: {"device": {"health": {"temperatures": {"core": 339.0}}}} (2)
1 Request core temperature of CPU
2 Response in Kelvin

/network

/network/gptp_grandmaster_id

TX: {"network": {"gptp_grandmaster_id": null}} (1)
RX: {"network": {"gptp_grandmaster_id": "0001f2fffe00489d"}} (2)
1 Request entity ID (IEEE 1722.1 ATDECC) of current gPTP grandmaster
2 Response: current grandmaster ID

/clock

/clock/sampling_rate

TX: {"clock": {"sampling_rate": null}} (1)
RX: {"clock": {"sampling_rate": 44100} (2)
1 Request sampling rate set by the user
2 Response in hertz
this may differ from the current sampling rate when the device is locked to a MADI signal (Intelligent Clock Control). In that case, the current sampling rate is shown in /clock/sources/(signal)/rate

/clock/current_sampling_rate

TX: {"clock": {"current_sampling_rate": null}} (1)
RX: {"clock": {"current_sampling_rate": 48000}} (2)
1 Request current sampling rate
2 Current rate is 48000

/clock/source

TX: {"clock": {"source": null}} (1)
RX: {"clock": {"source": "internal"} (2)
TX: {"clock": {"source": "wordclock"}} (3)
1 Request current clock source requested by user
2 Response: device is master
3 Set clock source to word clock (see clock/sources/ for possible values)

/clock/word_clock_single_speed

TX: {"clock": {"word_clock_single_speed": null}} (1)
RX: {"clock": {"word_clock_single_speed": false} (2)
TX: {"clock": {"word_clock_single_speed": true}} (3)
RX: {"clock": {"word_clock_single_speed": true}} (4)
1 Request word clock single speed status
2 Response (boolean)
3 Set word clock output to single speed
4 Device confirmation

/clock/reference_clock

TX: {"clock": {"reference_clock": null}} (1)
RX: {"clock": {"reference_clock": "madi_coaxial"}} (2)
1 Request the current clock source for the internal clock
2 Response

/clock/soundness

TX: {"clock": {"soundness": null}} (1)
RX: {"clock": {"soundness": {"state": "Good"}}} (2)
RX: {"clock": {"soundness": {"state":"Warning","cause":"ClockMasterNoSync"}}} (3)
1 Request the overall soundness state of the clock section.
2 Everything is properly synced.
3 There is a clock issue.

/clock/sources/(source)

Available sources:
internal
wordclock
madi_coaxial
madi_optical
avb_stream_1/pri
...
avb_stream_8/pri

Each source contains an object with three keys that must be polled individually. In case of AVB stream inputs, the sources are further divided into primary ("pri") and secondary port ("sec"). The secondary port is not shown if the device only has one network port.

RX:
"madi_coaxial": {
  "rate": 44100, (1)
  "sync": true,  (2)
  "soundness": { "state": "Good"} (3)
}, [...]
"avb_stream_8": {
  "pri": { (4)
    "rate": "NoLock",
    "sync": false,
    "soundness": {"state": "Inactive"}
  }
}
1 /rate Current sampling rate at input
2 /sync Sync status
3 /soundness Soundness
4 /pri for primary network port
TX: {"clock": {"sources": {"madi_coaxial": {"rate": null}}}} (1)
RX: {"clock": {"sources": {"madi_coaxial": {"rate": 44100}}}} (2)
1 Request the sampling rate at input MADI coaxial
2 Current sampling rate is 44.1 kHz

/input

Shows relevant settings for the input channels.

/input/madi

State and settings of the MADI inputs (apart from /clock/sources/madi_…​)

RX: {"input": {
      "madi": {
        "auto_input": false, (1)
        "coaxial": {
          "soundness": {
            "state": "Good" (2)
          }
        },
        "optical": {
          "soundness": {
            "state": "Inactive" (3)
          }
        }
}
1 Auto input (Redundancy) for MADI inputs
2 Soundness of MADI coaxial input
3 Soundness of MADI optical input

The auto input can be activated or deactivated with a boolean:

TX: {"input": {"madi": {"auto_input": true}}}

/input/avb

RX: {"input": {
 "avb": {
  "1": { (1)
      "channel_count": 8, (2)
      "format": "AAF", (3)
      "pri": { (4)
          "soundness": {
            "state": "Good" (5)
          },
          "avb_status": {
            "stream_id": [ 72, 11, 178, 208, 4, 88, 0, 0], (6)
            "dest_addr": [ 145, 224, 240, 0, 161, 5], (7)
            "state": "Streaming" (8)
          }
}}}}}

TX: {"input": {"avb": {"3": {"format": "AM824"}}}} (9)
RX: {"input":{"avb":{"1":{"pri":{"avb_status":{
        "stream_id":[72,11,178,220,38,82,0,0]}}}}}} (10)
1 Stream number (1-8)
2 Channel count (TX: null, 0 (CRF), 1-8, 12, 16)
3 Format (TX: null, AM824, AAF)
4 Primary or secondary (sec) port
5 Soundness (TX: null)
6 Stream ID of stream (TX: null, RX see below)
7 Destination of current stream (TX: null)
8 State of stream (TX: null)
9 Example: set stream format <10>
When changing the format or size of a stream, all connected streams will be briefly interrupted.

/output

/output/analog

Analog output settings

{"output":{
    "analog": {
        "soundness": { (1)
          "state": "RoutedButIssuesWithInput",
          "cause": "InputNoLock"
          },
        "1": { (2)
          "type": "analog_ref", (3)
          "reference_level": 13, (4)
          "mute": false, (5)
          "label": "Analog Out 1" (6)
        },
        "2": {[...]},
        [...]
        "32": {[...]}

         } } }
1 Soundness of analog output
2 Channel number
3 Output type
4 Reference level in dBu
5 Mute state
6 Channel label

/output/madi

{"output": {"madi": {
        "mode": 64, (1)
        "framesize": 48, (2)
        "coaxial": {
            "soundness": { (3)
                "state": "Unrouted"
            }
        },
        "optical": {
            "soundness": {
                "state": "Unrouted"
}}}}}
1 56 channel or 64 channel frame (TX: null, 56, 64)
2 48k or 96k frame (TX: null, 48, 96)
3 Soundness

/output/avb

RX: {"output": {
 "avb": {
  "1": { (1)
      "channel_count": 8, (2)
      "format": "AAF", (3)
      "pto": 2000000, (4)
      "pri": { (5)
        "soundness": {
          "state": "Inactive" (6)
        },
        "avb_status": {
          "stream_id": [
              0, (7)
              0,
              0,
              0,
              0,
              0,
              0,
              0
          ],
          "dest_addr": null, (8)
          "state": "Disabled" (9)
        }
}}}}

TX: {"input": {"avb": {"1": {"pri":{"avb_status": {"stream_id": null}}}}}} (10)
RX: {"input":{"avb":{"1":{"pri":{"avb_status":{
        "stream_id":[72,11,178,220,38,82,0,0]}}}}}} (11)
1 Stream number (1-8)
2 Channel count (TX: null, 0 (CRF), 1-8, 12, 16)
3 Format (TX: null, AM824, AAF)
4 Presentation time offset (TX: null, 0-2000000)
5 Primary or secondary (sec) port
6 Soundness (TX: null)
7 Stream ID of stream (TX: null, RX see below)
8 Destination of current stream (TX: null)
9 State of stream (TX: null)
10 Example: request stream ID
11 Stream ID 48:0b:b2:dc:26:52:00:00 in decimal format
When changing the format or size of a stream, all incoming and outgoing streams are briefly interrupted.

/routing

All output channels are represented as keys within 'port' objects. Routings are created by adding a value ["inputport", channelnumber] to the output channel.

"routing": {
    "madi_coaxial": { (1)
        "1": [ (2)
            "unrouted", (3)
            1 (4)
        ],
        "2": [
            "unrouted",
            1
        ], ...
1 TX: phones, (analog), madi_coaxial, madi_optical, avb1 - avb8
2 TX: 1-64: channel number of output in current port
3 TX: null, port as above
4 TX: input channel number