Multi-instance M4L device: how to reliably attach track name to OSC audio data (RMS + spectrum)?

Sergey KORTIKOV's icon

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!

Source Audio's icon

why don't you pack all in a single OSC message ?

/ableton/xxx "Track Name" rms Spectrum

Sergey KORTIKOV's icon

"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."

Source Audio's icon

you can get that few infos easier