A Swift framework for orchestrating AES70/OCA devices using profiles — virtual representations of device configurations that can be created offline, bound to physical devices at runtime, and serialised for persistence.
Built on SwiftOCA.
AES70Orchestrator lets you describe a device's object hierarchy in YAML, then create an arbitrary number of profiles that match that schema. Each profile gets its own block hierarchy of local proxy objects that you can manipulate as you would on any OCA device — without a physical device being present.
The key feature is device binding: you can bind a profile to one or more remote devices. The match property in the YAML schema describes which object numbers on the remote device to target, and the mask determines how many profiles can be bound to a single device. Once bound, property change events are forwarded bidirectionally between local proxy objects and their corresponding remote device objects.
A profile represents an end-user of a personal monitor mixer. Each mixer can support multiple users (reflected in the match mask). This enables:
- Offline provisioning — create and configure user profiles without any device connected
- User mobility — move users and their mix settings between devices by rebinding profiles
- State persistence — serialise all device bindings and profile parameter sets, retrievable over OCA
Devices are described in YAML. Here is an example matching SwiftOCA's OCADevice example:
# Block (ONo 10000)
# BooleanActuator x8 (ONos 10010..10017)
# Gain (ONo 10020)
device:
name: OCADevice
profiles:
- OCADevice:
- Block:
class-id: 1.1.3
match: 0x00002710/0x00000000
object-number: 0x00001000/0x000000F0
action-objects:
- "Actuator(0,0)":
class-id: 1.1.1.1.1
match: 0x0000271A/0x00000000
object-number: 0x00002000/0x000000F0
# ... more actuators ...
- Gain:
class-id: 1.1.1.5
match: 0x00002724/0x00000000
object-number: 0x00002010/0x000000F0Each object in the schema specifies:
class-id— dotted OCA class ID (e.g.1.1.1.5forOcaGain), resolved via the device class registry. Omit for containers with children (inferred asOcaBlock) or leaves (inferred asOcaRoot).match— remote object number and mask (oNo/mask). The mask bits determine how many profile instances can be bound to a single device.object-number(synonym:ono) — optional local object number and mask for the proxy object. If omitted, the orchestrator allocates a local object number from the reserved range (below 4096) to avoid conflicts with device-assigned object numbers.action-objects(synonym:members) — list of child objects within a block.lock-remote— iftrue, lock remote objects when bound. Defaults tofalse.include-props— optional list of property IDs to forward between local and remote objects. When set, only listed properties are forwarded.exclude-props— list of property IDs to never forward between local and remote objects.
When using the mapping form for a profile, the following options are available:
autobind— iftrue, profiles of this schema are automatically bound to all discovered devices and cannot be manually bound/unbound. Defaults tofalse.
profiles:
- AutoProfile:
autobind: true
blocks:
- Gain:
class-id: 1.1.1.5
match: 0x00000200/0x0000000FThe framework exposes an OCA device with the following structure:
- OcaCoordinator (ONo 1024) — an
OcaManagerthat manages profiles. Provides OCP.1 methods for creating, binding, finding, and deleting profiles, as well as exporting/importing state. - Profiles block (ONo 1025) — contains
OcaProfileagents, one per created profile. - Profile Proxies block (ONo 1026) — contains per-schema sub-blocks, each containing per-profile sub-blocks with the local proxy objects that mirror the device schema.
Each OcaProfile is an OcaAgent with:
- A read-only
schemaproperty identifying which device schema it belongs to - A read-only
boundDeviceslist - A proxy block containing the local object hierarchy matching the schema
The profile's label is synchronised from its proxy block — set the label on the proxy block and it propagates to the profile.
- AES70Orchestrator — server-side (device) library
- AES70OrchestratorClient — client-side controller library with
@OcaPropertydeclarations andsendCommandRrq-based methods
State can be saved to and loaded from ZIP archives (file-based or in-memory OcaLongBlob). The archive contains a JSON manifest of profiles and their device bindings, plus serialised parameter datasets for each profile's proxy block. State export/import is also accessible over OCP.1.
- SwiftOCA — OCA/OCP.1 implementation
- Yams — YAML schema parsing
- ZIPFoundation — persistence archives
- swift-log — logging
- swift-async-algorithms — debounced persistence monitor
Apache License 2.0. See LICENSE.txt.