Max-MSP ambisonic renderer
Ambix_3th_order-sound_ctrl.maxpat
Host: Windows NUC, Max 9.1.5
Layer: output (sound, back end)
In: OSC positions (UDP 10000) + 16 audio channels over Dante
Out: 16 loudspeaker feeds + 1 subwoofer feed over Dante
This patch is the rendering engine behind Ambisonics sound control. It receives the positions of up to sixteen sound sources and their audio, encodes them into a third-order ambisonic sound field, and decodes that field to the lab's measured, irregular layout of sixteen loudspeakers plus a subwoofer, all in real time. Most users never touch it: the TouchDesigner component is the interface, and the renderer runs on a dedicated machine. Splitting the work this way keeps audio rendering apart from the graphics and tracking load on the main workstation. It also keeps the decoder calibration in one place, independent of any project.
Role in the setup
The renderer is the second half of the lab's spatial sound chain. Ambisonics sound control decides where each sound is and what it plays. The renderer turns that into speaker signals for this particular room. Because the calibration lives here, any TouchDesigner project that sends positions and audio in the expected format sounds correct in the lab without project-specific tuning.
System context
| Machine | Role |
|---|---|
| HP Z8 workstation | TouchDesigner: tracking, content and source audio. Audio goes onto the Dante network through Dante Via. Positions are sent over OSC. |
| Windows NUC | Max 9.1.5 running this patch. Audio input and output go through Dante Virtual Soundcard in ASIO mode. |
| Dante network | carries all audio between the machines and to the amplifiers and loudspeakers at 48 kHz. Routing is managed in Dante Controller. |
| Authoring machine (Mac) | where the patch is edited. It is not part of the live chain. Patch iterations reach the NUC through a shared OneDrive folder. |
Signal processing pipeline
- Position intake (OSC).
udpreceive 10000receives the positions. The patch routes the addresses/tx1 /ty1 /tz1…/tx16 /ty16 /tz16(one triplet per source), a tracked listener/lx1 /ly1 /lz1, a global/gain_range, per-source ranges/range_gain1…/range_gain16, and/_samplerate(information only). - Cartesian → spherical. Each source position (X = width, Y = height, Z = depth, metres) is converted to azimuth, elevation and distance relative to the reference listening point (X = 0, Y = 1.5, Z = 2.5). A sign-preserving minimum-magnitude floor on the depth term removes the singularity when a source is at exactly the reference depth.
- Gain. Each source's level falls with its distance to the listening reference. The gain range is the distance in metres at which the level reaches zero. It is set globally (
/gain_range) or per source (/range_gain1…/range_gain16); per source, it is fed by Rangegain in TouchDesigner. The reference is either fixed or tracked. An inversion toggle mirrors the tracked listener through the room centre to correct for the orientation of the tracking. Direction never comes from the listener, because listener orientation cannot be tracked reliably. A minimum floor on the range parameter prevents a division by zero while the patch loads. A global "gain active" switch sets all sources to full gain for direction-only tests. - Encoding.
ambiencode~ 3 16(ICST) encodes the 16 audio inputs (adc~ 1–16, from Dante) into a third-order AmbiX field: 16 channels, ACN order, SN3D normalisation. - File input. Two looped players (
buffer~+groove~, 16 channels each) add pre-encoded third-order B-format WAV files to the field before decoding. Each player has its own toggle and is off by default. (In development.) - Decoding.
ambidecode~ 3 16(ICST) decodes the field to the 16 measured loudspeaker positions. Each speaker is defined by azimuth, elevation and distance in a decoder grid that can be edited live. - Subwoofer. The omnidirectional W component (ACN 0) is taken from the encoder, low-pass filtered (
lores~, 100 Hz) and sent to channel 17. - Output.
dac~ 1–17sends the speaker feeds to Dante.
Loudspeaker calibration
Speaker positions were measured in the room and converted to decoder coordinates with a purpose-built interactive calibration tool, which has a top-down view and an elevation view. The tool exports azimuth, elevation and distance per speaker. These values are typed into the decoder grid, take effect immediately, and need no new patch version. The encoder's speaker-matched default positions (used in calibration mode) are derived from the same data, so the two stay consistent.
| # | Ring | X | Y | Z | Azimuth | Elevation | Distance |
|---|---|---|---|---|---|---|---|
| 1 | ground | −2.6 | 0.5 | 4.5 | −127.57° | −16.95° | 3.43 m |
| 2 | ground | −2.6 | 0.5 | 2.5 | −90.00° | −21.04° | 2.79 m |
| 3 | ground | −2.6 | 0.5 | 0.1 | −47.29° | −15.78° | 3.68 m |
| 4 | ground | 0 | 0.5 | −0.3 | 0.00° | −19.65° | 2.97 m |
| 5 | ground | 2.6 | 0.5 | 0.1 | 47.29° | −15.78° | 3.68 m |
| 6 | ground | 2.6 | 0.5 | 2.5 | 90.00° | −21.04° | 2.79 m |
| 7 | ground | 2.6 | 0.5 | 4.5 | 127.57° | −16.95° | 3.43 m |
| 8 | rear | 0 | 3.0 | 7.15 | 180.00° | 17.88° | 4.89 m |
| 9 | high | −2.5 | 3.7 | 3.25 | −106.70° | 40.13° | 3.41 m |
| 10 | high | −2.5 | 3.7 | 1.75 | −73.30° | 40.13° | 3.41 m |
| 11 | high | −1.25 | 3.7 | 0 | −26.57° | 38.21° | 3.56 m |
| 12 | high | 1.25 | 3.7 | 0 | 26.57° | 38.21° | 3.56 m |
| 13 | high | 2.5 | 3.7 | 1.75 | 73.30° | 40.13° | 3.41 m |
| 14 | high | 2.5 | 3.7 | 3.25 | 106.70° | 40.13° | 3.41 m |
| 15 | high | 1.25 | 3.7 | 5 | 153.43° | 38.21° | 3.56 m |
| 16 | high | −1.25 | 3.7 | 5 | −153.43° | 38.21° | 3.56 m |
Convention: azimuth 0° points from the listening point towards the north wall. Positive azimuth turns towards +X. Z increases towards the entrance. The table also appears in the Lab model.
Operating modes
| Mode | Options | Default |
|---|---|---|
| Direction (global and per source) | live tracked position, or a fixed position that matches the source's own speaker (calibration) | tracked |
| Test audio (global and per source) | live Dante input, or a looped voice recording | live |
| Listener reference | fixed point, or tracked listener (with optional mirroring) | — |
| Gain active | distance-based gain, or full gain on all sources | on |
| Ambisonic file players (2) | off / play | off |
A debug panel shows each source's tracked position, its distance to the listener and the gain value sent to the encoder. This makes reactivity problems visible without console output.
Implementation notes
- Re-evaluation in
expr. In practice, Max'sexpronly reliably fires on its leftmost inlet. The distance and listener-blend expressions therefore route all their inputs throughpak/unpack, which forces re-evaluation whenever any input changes. - Sample rate. All content has to arrive at 48 kHz. Dropouts with 44.1 kHz material turned out to be a resampling problem on the sending side, not in the renderer.
- State. An encoder instance that has been corrupted by invalid coefficients does not recover when the patch file is reopened. Max has to be fully restarted. The same applies to stale test-audio buffers.
Limitations and open questions
- Directional rendering. Checking the panning across this irregular layout is ongoing work. A controlled comparison with a regular reference layout is planned.
- Listener model. There is one listening reference. Multiple listeners and listener orientation are outside the current scope.
- Built-in distance model. ICST's own distance attenuation is disabled in favour of the custom gain model above. It remains an option.
- Speaker aiming. The decoder stores position only. It does not store per-speaker aim (yaw/pitch).
Outlook
- A Dante input for B-format audio rendered in TouchDesigner, mixed in at the same point as the file players.
- A control interface in TouchDesigner, so live operation no longer requires editing the Max patch.
- A head-tracked headphone mode ("Augmented Audio Reality") alongside the loudspeaker array.
Availability
The renderer is not part of the public Td-updates repository. It runs on the lab's NUC and is maintained by the lab.
Relations
- ← Ambisonics sound control (OSC positions, Dante audio)
- ↔ Lab model (speaker positions)
- Overview: Lab Tools
- Hardware: Inventory (loudspeakers, renderer computer, Dante network)
References
- ICST Ambisonics externals for Max: Institute for Computer Music and Sound Technology, Zurich University of the Arts.
- AmbiX format: ACN channel ordering, SN3D normalisation.