Multi-instance M4L device: how to reliably attach track name to OSC audio data (RMS + spectrum)?
Hi everyone,
I'm building a Max for Live device that gets placed on multiple audio tracks
(8-12 instances) and sends OSC data to a Python backend for analysis.
Each instance must send three types of OSC messages:
/ableton/track/name "TrackName"
/ableton/track/rms "TrackName" -12.5
/ableton/track/spectrum "TrackName" 0.1 0.2 0.3 ... (12 float values, 12-band fffb~ analyzer)
The track name is obtained via:
live.thisdevice → live.path this_device canonical_parent → live.object → get name → route name → tosymbol
This part works correctly — I confirmed with [print] that tosymbol outputs the
correct track name (e.g. "PERC 65", "MELODY 3") for each instance.
THE PROBLEM:
I cannot reliably combine the track name (symbol) with the audio data
(float values from snapshot~) into a single OSC message inside Max.
What I tried:
1. [pak symbol_default 0. 0. ... 0.] with name on left (cold) inlet and
12 snapshot~ values on right inlets. The name arrives via inlet 3 of
the subpatcher. Result: [pak] outputs the default symbol "s" instead
of the actual name — the name doesn't reach the symbol-inlet in time
before snapshot~ triggers output.
2. [pack ...] instead of [pak]. Result: no output at all (left inlet is
hot/symbol but never receives a list-triggering bang in sync with audio).
3. Sending name to a separate /ableton/track/name OSC message and letting
the Python backend correlate name+RMS+spectrum by timing
(last_received_name pattern). Works partially but unreliable when
multiple instances send simultaneously — names get mixed up between tracks.
4. [t s s] (trigger) to duplicate the symbol to two destinations — no effect.
5. [value @scope local] as a name buffer — couldn't get the local scope
to work properly per-instance.
QUESTION:
What is the recommended pattern in Max for Live to:
(a) capture the track name once per instance
(b) combine it with continuously-updating audio data (snapshot~ output)
(c) send it as a single OSC message via udpsend with the name as the
first OSC argument
Specifically — should I use:
- A different object than [pak]/[pack]?
- [bondo] for synchronization?
- CNMAT odot's [o.pack]?
- A different architecture entirely (e.g., one master device collecting
all data instead of per-track instances)?
Any working example or pattern reference would be extremely appreciated.
Setup:
Max 8 / Live 12, Windows 11
Python backend uses python-osc to receive on UDP 11001
Thank you!


why don't you pack all in a single OSC message ?
/ableton/xxx "Track Name" rms Spectrum

"Thank you so much! That's exactly the elegant solution I was missing — packing everything into a single OSC message. Going to refactor the device now."
you can get that few infos easier
