Several [udpsend] sending to the same IP and port on M4L
Hi there,
I'm working on a Max for Live setup and trying to create a solid and efficient structure.
Currently, I have a single M4L device with a [udpsend]
object that sends OSC messages to another Max patch. The [udpsend]
receives the OSC messages via [send]
and [receive]
from another M4L device inserted on multiple tracks in Ableton Live. This method works well for standard OSC messages, as any delay is acceptable since the messages are not part of the musical time structure in Live.
However, I'm encountering a problem when using [o.compose]
to send OSC bundles. These bundles, being volatile full packets, often arrive late to [udpsend]
due to delays caused by [send]
and [receive]
between tracks. As a result, I frequently see this error in the receiving Max patch:o.route: received something that is neither an OSC bundle nor a message.
To solve this, I'm considering an alternative approach where each M4L device on each track has its own [udpsend]
. All of these instances would send directly to the same IP and port.
Before I implement this, I want your feedback on whether this setup will work reliably, especially at scale:
Will having multiple
[udpsend]
instances, all sending to the same IP and port, create any conflicts or performance issues?Are there any limitations with UDP or Max for Live that I should consider in this scenario?
Has anyone tried a similar setup and can share any insights, best practices, or potential pitfalls?
Any guidance or experience you can share would be greatly appreciated. Thanks in advance for your help!
Do you mean by 'another Max patch' a max patch in an m4l device, or in a separate instance of Max?
If the former, and you're sending everything around inside Ableton/m4l, there's really no need to use UDP at all -- you can just send regular Max messages in OSC format (using sprintf, combine, whatever) and parse it on the other end. If you're locked into o.compose, you can use o.atomize to convert the FullPacket to regular messages, and just use normal s/r pairs.
If the latter, you aeren't obliged to send OSC data as full packets, so you could again use o.atomize to send out the OSC-formatted messages over UDP that aren't FullPacket-formatted. Just skip the 'CNMAT' argument to udpreceive on the other end.
Might be easier than rebuilding your whole message architecture...
\M
From my experience, multiple udpsend is fine.
But be careful with multiple udpreceive, especially if they are all listening to the same ip and port. Because it means you need to have some routing after that, and it will be processed for each instance.
I recently worked on a project with over 400 instances of an abstraction with both udpsend and udpreceive in it. Receiving OSC did cause a lot of slowdowns (it was a jit.gl intensive patch and the fps went very bad when receiving OSC). So then I used a single updreceive, splitted the incoming messages with o.route and then dispatched them to the +400 abstractions with combinations of send/receive and other o.route and it was absolutely fine.
What I did not try though, is if all udpsend are sending messages at the same time. But my guess is that it should not require much more processing compared to having only one centralized udpsend, or maybe actually even less because there will be less routing involved.
@Mattyo, thank you for your response!
Just to clarify, I’m using two M4L devices and an external Max patch (independent of Live).
One of the M4L devices originally had the single [udpsend]
, which was placed on a single track in Live and received messages via [send]
/[receive]
from the second M4L device. That second device is spread across multiple tracks in Live, generating OSC messages simultaneously from all those tracks using [send]
, [receive]
, and [o.atomize]
.
However, my concern arises because I can no longer rely on [o.atomizer]
due to the infrastructure I’ve implemented in the external Max patch. I now need to send OSC messages as bundles to receive the data grouped together, which is crucial for my setup.
@TFL, thank you for your reply as well!
It’s reassuring to know you’ve managed to work with up to 400 [udpsend]
instances simultaneously. During development, I’m currently working with only 22 instances to keep things manageable, but the expectation is to scale up to many dozens, potentially more. Knowing you’ve successfully implemented this approach gives me confidence that it’s viable.
I’m using a single [udpreceive]
for handling the incoming OSC messages in the external Max patch, I hope to avoid any performance issues or surprises as the number of tracks increases significantly.