How can I listen for an OSCAddressPattern?


#1

The OSCReceiver::addListener assert fails if you pass it an address with wild cards (i.e. an OSC Address Pattern).  There doesn't seem to be a way to listen to a particular OSCAddressPattern and so from what I can tell, if I want to do that, I have to just add a general listener and then examine/route the actual address myself. That would be fine except that if I can't define particular patterns and listen for them separately, how do I arrange for some OSC messages to be received on a RealTime listener vs the regular MessageCallbackLoop?

 

Do I have to create separate OSCReceivers and listen on different ports to do this?

 

Thanks


#2

Followup question --- the actual address that is received/accessed by oscMessageReceived seems only accessable through the OSCMessage parameter but that class has only getAddressPattern which returns an OSCAddressPattern, not an OSCAddress.

Now, the OSCAddressPattern (which is the one that can take a wild card) has a match method but it will only match against an OSCAddress, which is not available from a message

As a hack I've done it by writing

       OSCAddressPattern p("/*/*/midi");

       OSCAddress m(message.getAddressPattern().toString());

       if (p.matches(m)) ....

 

but it doesn't seem right that I'm supposed to manually get the string back.   Shouldn't OSCMessage have a method that returns an OSCAddress type?

Also, the OSCAddressPattern should have methods that will access those partial address matches, e.g. if I send a message that looks like

        /V1/1/midi  .....

and I have a pattern that looks like

      /*/*/midi

then I'd like to be able to extract that V1 and 1 respectively.

 

Am I missing something or are these OSC classes incomplete?


#3

This is not how OSC works, see the specification: http://opensoundcontrol.org/

The OSC messages can have wildcards, so you can route them to various receivers. However the OSC receivers only listen to a single address, you can't listen to a pattern.

It seems that you are trying to use it the other way around, which is not supported by OSC (or the JUCE classes).

Shouldn't OSCMessage have a method that returns an OSCAddress type?

No, because you can't generally convert an OSCAddressPattern to an OSCAddrress. The former can have wildcards, while the latter can't.

As a hack I've done it by writing

       OSCAddressPattern p("/*/*/midi");

       OSCAddress m(message.getAddressPattern().toString());

       if (p.matches(m)) ....

I think this "hack" won't work. The message's address pattern is allowed to contain wildcards. And then surely this line of code will fail: OSCAddress m(message.getAddressPattern().toString());

Maybe instead of trying to hack this in, you should re-think the way you use OSC addresses in your setup?


#4

Thanks, Timur. I had actually tried to look at the specification before reaching out but opensoundcontrol.org has been down for several days (at least) so I have been having trouble finding the specs.

But you're right --- I am trying to emulate the OSC-Route object that exists for MaxMSP, i.e. receive any OSC message and then route it based on its contents. I didn't realize that actual messages sent over UDP could contain wild cards, I thought the idea was to match an incoming message with some pattern so as to determine how to process it, much like one might compare an incoming string with a regex


#5

 I thought the idea was to match an incoming message with some pattern so as to determine how to process it

Yes, in principle, but the OSC idea is that the incoming message carries the pattern, instead of the receiver.

For what you want to do, you have to catch all OSC traffic using an OSCReceiver::Listener, and then implement your own routing for this. You can't use the OSC pattern matching stuff directly because it's not intended to work this way around.

If, for your custom routing, you want to use the same matching rules as OSC pattern matching does, you can use your code above (but add an if (! message.getAddressPattern().containsWildcards())

Otherwise you can convert the addresses and addresspatterns to strings and use something else, such as std::regex for example, or whatever else you like to use.


#6

Yep --- again, that's what I ended up doing --- I guess I should have really experimented more before posting questions. However, I was hoping to avoid such things as regex --- I know computers are fast but the notion of receiving realtime OSC events at high speed and then running regex searches against them sounded like a horrible cost in the context of a realtime network thread  (and yes, I know I'm not supposed to do premature optimization without measuring first smiley)


#7

Well, even if you use JUCE's OSC wildcard matcher instead of std::regex, the former is internally implemented using a hand-written recursive descent parser. I'd guess this would be comparable in speed to std::regex (which does more stuff but is probably also more hardcore optimised). So you need to pay that cost anyway. And probably it doesn't matter :-)